mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 19:05:02 -04:00
rendering: more animations
* Known bugs: Not all textures are animated
This commit is contained in:
parent
fa6990b0b2
commit
d348f8b7c5
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2021 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.textures
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.gui.rendering.textures.properties.AnimationFrame
|
||||||
|
|
||||||
|
class TextureAnimation(
|
||||||
|
val texture: Texture,
|
||||||
|
) {
|
||||||
|
var currentFrameIndex = 0
|
||||||
|
var currentTime = 0L
|
||||||
|
|
||||||
|
val animationProperties = texture.properties.animation!!
|
||||||
|
|
||||||
|
fun getCurrentFrame(): AnimationFrame {
|
||||||
|
return animationProperties.frames[currentFrameIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAndSetNextFrame(): AnimationFrame {
|
||||||
|
currentFrameIndex = getNextIndex()
|
||||||
|
currentTime = 0L
|
||||||
|
|
||||||
|
return animationProperties.frames[currentFrameIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getNextFrame(): AnimationFrame {
|
||||||
|
return animationProperties.frames[getNextIndex()]
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getNextIndex(): Int {
|
||||||
|
var nextFrameIndex = currentFrameIndex + 1
|
||||||
|
|
||||||
|
if (nextFrameIndex == animationProperties.frames.size) {
|
||||||
|
nextFrameIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextFrameIndex
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,6 @@ import de.bixilon.minosoft.Minosoft
|
|||||||
import de.bixilon.minosoft.data.assets.MinecraftAssetsManager
|
import de.bixilon.minosoft.data.assets.MinecraftAssetsManager
|
||||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
|
||||||
import de.bixilon.minosoft.util.logging.Log
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
import de.matthiasmann.twl.utils.PNGDecoder
|
import de.matthiasmann.twl.utils.PNGDecoder
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
@ -74,7 +73,7 @@ class TextureArray(val allTextures: MutableList<Texture>) {
|
|||||||
it.add(texture)
|
it.add(texture)
|
||||||
texture.properties.animation?.let { properties ->
|
texture.properties.animation?.let { properties ->
|
||||||
properties.animationId = animator.animatedTextures.size
|
properties.animationId = animator.animatedTextures.size
|
||||||
animator.animatedTextures.add(texture)
|
animator.animatedTextures.add(TextureAnimation(texture))
|
||||||
|
|
||||||
val bytesPerTexture = size.x * size.y * PNGDecoder.Format.RGBA.numComponents
|
val bytesPerTexture = size.x * size.y * PNGDecoder.Format.RGBA.numComponents
|
||||||
val fullBuffer = texture.buffer!!
|
val fullBuffer = texture.buffer!!
|
||||||
@ -147,24 +146,22 @@ class TextureArray(val allTextures: MutableList<Texture>) {
|
|||||||
const val TEXTURE_MAX_RESOLUTION = 1024
|
const val TEXTURE_MAX_RESOLUTION = 1024
|
||||||
|
|
||||||
val DEBUG_TEXTURE = Texture.getResourceTextureIdentifier(textureName = "block/debug")
|
val DEBUG_TEXTURE = Texture.getResourceTextureIdentifier(textureName = "block/debug")
|
||||||
|
|
||||||
|
private const val INTS_PER_ANIMATED_TEXTURE = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class Animator {
|
inner class Animator {
|
||||||
val animatedTextures: MutableList<Texture> = mutableListOf()
|
val animatedTextures: MutableList<TextureAnimation> = mutableListOf()
|
||||||
private var animatedBufferDataId = -1
|
private var animatedBufferDataId = -1
|
||||||
|
|
||||||
|
var lastRun = 0L
|
||||||
private var currentTick = 0
|
private lateinit var animatedData: IntArray
|
||||||
private var lastTickIncrementTime = 0L
|
|
||||||
|
|
||||||
|
|
||||||
lateinit var animatedData: IntArray
|
|
||||||
|
|
||||||
var initialized = false
|
var initialized = false
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun initBuffer() {
|
fun initBuffer() {
|
||||||
animatedData = IntArray(32 * 4) // 4 data ints per entry
|
animatedData = IntArray(32 * INTS_PER_ANIMATED_TEXTURE) // 4 data ints per entry
|
||||||
|
|
||||||
|
|
||||||
animatedBufferDataId = glGenBuffers()
|
animatedBufferDataId = glGenBuffers()
|
||||||
@ -184,21 +181,36 @@ class TextureArray(val allTextures: MutableList<Texture>) {
|
|||||||
if (!Minosoft.getConfig().config.game.animations.textures) {
|
if (!Minosoft.getConfig().config.game.animations.textures) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
if (currentTime - lastTickIncrementTime >= ProtocolDefinition.TICK_TIME) {
|
val deltaLastDraw = currentTime - lastRun
|
||||||
currentTick++
|
lastRun = currentTime
|
||||||
lastTickIncrementTime = currentTime
|
|
||||||
}
|
for (textureAnimation in animatedTextures) {
|
||||||
|
var currentFrame = textureAnimation.getCurrentFrame()
|
||||||
|
textureAnimation.currentTime += deltaLastDraw
|
||||||
|
|
||||||
|
if (textureAnimation.currentTime >= currentFrame.animationTime) {
|
||||||
|
currentFrame = textureAnimation.getAndSetNextFrame()
|
||||||
|
textureAnimation.currentTime = 0L
|
||||||
|
}
|
||||||
|
|
||||||
|
val nextFrame = textureAnimation.getNextFrame()
|
||||||
|
|
||||||
|
val interpolation = if (textureAnimation.animationProperties.interpolate) {
|
||||||
|
(textureAnimation.currentTime * 100) / currentFrame.animationTime
|
||||||
|
} else {
|
||||||
|
0L
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (texture in animatedTextures) {
|
val baseAnimatedData = (textureAnimation.texture.arrayId shl 24) or textureAnimation.texture.arrayLayer
|
||||||
val animationProperties = texture.properties.animation!!
|
|
||||||
|
|
||||||
val arrayOffset = animationProperties.animationId * 4
|
val arrayOffset = textureAnimation.animationProperties.animationId * INTS_PER_ANIMATED_TEXTURE
|
||||||
|
|
||||||
animatedData[arrayOffset] = (texture.arrayId shl 24) or (texture.arrayLayer + (currentTick % animationProperties.frameCount))
|
animatedData[arrayOffset] = baseAnimatedData or currentFrame.index
|
||||||
animatedData[arrayOffset + 1] = (texture.arrayId shl 24) or (texture.arrayLayer + 1) + (currentTick % animationProperties.frameCount)
|
animatedData[arrayOffset + 1] = baseAnimatedData or nextFrame.index
|
||||||
animatedData[arrayOffset + 2] = 0
|
animatedData[arrayOffset + 2] = interpolation.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2021 Moritz Zwerger
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.bixilon.minosoft.gui.rendering.textures.properties
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
|
|
||||||
|
data class AnimationFrame(
|
||||||
|
val index: Int,
|
||||||
|
val time: Int,
|
||||||
|
) {
|
||||||
|
val animationTime = time * ProtocolDefinition.TICK_TIME
|
||||||
|
}
|
@ -20,12 +20,17 @@ data class AnimationProperties(
|
|||||||
val interpolate: Boolean = false,
|
val interpolate: Boolean = false,
|
||||||
var width: Int = -1,
|
var width: Int = -1,
|
||||||
var height: Int = -1,
|
var height: Int = -1,
|
||||||
@Json(name = "frametime") val frameTime: Int = 1,
|
@Json(name = "frametime") private val frameTime: Int = 1,
|
||||||
val frames: Any = Any(),// ToDo,
|
@Json(name = "frames") private val _frames: List<Any> = listOf(),
|
||||||
) {
|
) {
|
||||||
|
@Transient
|
||||||
|
lateinit var frames: Array<AnimationFrame>
|
||||||
|
private set
|
||||||
|
|
||||||
var animationId = -1
|
var animationId = -1
|
||||||
|
|
||||||
var frameCount = -1
|
var frameCount = -1
|
||||||
|
private set
|
||||||
|
|
||||||
fun postInit(texture: Texture) {
|
fun postInit(texture: Texture) {
|
||||||
if (width == -1) {
|
if (width == -1) {
|
||||||
@ -36,5 +41,26 @@ data class AnimationProperties(
|
|||||||
}
|
}
|
||||||
|
|
||||||
frameCount = texture.size.y / height
|
frameCount = texture.size.y / height
|
||||||
|
|
||||||
|
val frames: MutableList<AnimationFrame> = mutableListOf()
|
||||||
|
|
||||||
|
if (_frames.isEmpty()) {
|
||||||
|
for (i in 0 until frameCount) {
|
||||||
|
frames.add(AnimationFrame(i, frameTime))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (frame in _frames) {
|
||||||
|
if (frame is Number) {
|
||||||
|
frames.add(AnimationFrame(frame.toInt(), frameTime))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
check(frame is Map<*, *>) { "Invalid frame: $frame" }
|
||||||
|
|
||||||
|
frames.add(AnimationFrame((frame["index"] as Number).toInt(), (frame["time"] as Number?)?.toInt() ?: frameTime))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.frames = frames.toTypedArray()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,5 @@ package de.bixilon.minosoft.gui.rendering.textures.properties
|
|||||||
data class TextureProperties(
|
data class TextureProperties(
|
||||||
val blur: Boolean = false,
|
val blur: Boolean = false,
|
||||||
val clamp: Boolean = false,
|
val clamp: Boolean = false,
|
||||||
|
// ToDo: mipmaps
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user