particle texture (sprite) animations

This commit is contained in:
Bixilon 2021-05-26 12:34:30 +02:00
parent f138cfe709
commit 70c9986acc
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
6 changed files with 107 additions and 36 deletions

View File

@ -39,6 +39,7 @@ class ParticleMesh : Mesh() {
texture.uvEnd.x,
texture.uvEnd.y,
Float.fromBits(textureLayer),
Float.fromBits(texture.properties.animation?.animationId ?: -1),
scale,
Float.fromBits(tintColor.rgba),
))
@ -58,15 +59,17 @@ class ParticleMesh : Mesh() {
glEnableVertexAttribArray(index++)
glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, (7 * Float.SIZE_BYTES).toLong())
glEnableVertexAttribArray(index++)
glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, (8 * Float.SIZE_BYTES).toLong())
glEnableVertexAttribArray(index++)
super.unbind()
}
override fun draw() {
glBindVertexArray(vao)
glDrawArrays(GL_POINTS, 0, 1)
glDrawArrays(GL_POINTS, 0, primitiveCount)
}
companion object {
private val FLOATS_PER_VERTEX = 8
private val FLOATS_PER_VERTEX = 9
}
}

View File

@ -21,25 +21,25 @@ import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent
import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.textures.Texture
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.MMath
import glm_.vec3.Vec3
import java.util.concurrent.ThreadLocalRandom
class ParticleRenderer(
private val connection: PlayConnection,
val renderWindow: RenderWindow,
) : Renderer {
private val particleShader = Shader(
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "particle"),
)
private lateinit var particleShader: Shader
private var particleMesh = ParticleMesh()
private val texture = Texture(DUMMY_PARTICLE_RESOURCE_LOCATION)
override fun init() {
particleShader.load()
@ -56,25 +56,39 @@ class ParticleRenderer(
}
override fun postInit() {
particleShader = Shader(
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "particle"),
defines = mapOf("ANIMATED_TEXTURE_COUNT" to MMath.clamp(renderWindow.textures.animator.animatedTextures.size, 1, TextureArray.MAX_ANIMATED_TEXTURE)),
)
particleShader.load()
renderWindow.textures.use(particleShader, "textureArray")
renderWindow.textures.animator.use(particleShader, "AnimatedDataBuffer")
}
var last = 0L
override fun draw() {
particleShader.use()
val time = System.currentTimeMillis()
if (time - last >= ProtocolDefinition.TICK_TIME * 2000) {
particleMesh.unload()
particleMesh = ParticleMesh()
// thanks: https://gamedev.stackexchange.com/questions/113147/rotate-billboard-towards-camera
val position = Vec3(0, 6, 0)
particleMesh.addVertex(position, 1.0f, texture, ChatColors.RED)
val random = ThreadLocalRandom.current()
fun randomFlot(min: Float, max: Float): Float {
return min + random.nextFloat() * (max - min)
}
for (i in 0 until 123456) {
particleMesh.addVertex(Vec3(randomFlot(0.0f, 200.0f), randomFlot(6.0f, 200.0f), randomFlot(0.0f, 200.0f)), randomFlot(0.05f, 0.2f), texture, ChatColors.getRandomColor())
}
particleMesh.load()
last = time
}
particleMesh.draw()
}

View File

@ -33,7 +33,7 @@ uniform mat4 viewProjectionMatrix;
layout(std140) uniform AnimatedDataBuffer
{
uvec4 globalAnimationData[ANIMATED_TEXTURE_COUNT];
uvec4 uAnimationData[ANIMATED_TEXTURE_COUNT];
};
#include "minosoft:color"
@ -52,7 +52,7 @@ void main() {
return;
}
uvec4 data = globalAnimationData[animationIndex];
uvec4 data = uAnimationData[animationIndex];
uint firstTexture = data.x;
uint secondTexture = data.y;
uint interpolation = data.z;

View File

@ -13,20 +13,34 @@
#version 330 core
out vec4 outColor;
out vec4 foutColor;
flat in uint finTextureIndex;
in vec3 finTextureCoordinates;
flat in uint finTextureIndex1;
in vec3 finTextureCoordinates1;
flat in uint finTextureIndex2;
in vec3 finTextureCoordinates2;
flat in float finInterpolation;
in vec4 finTintColor;
#include "minosoft:texture"
void main() {
vec4 texelColor = getTexture(finTextureIndex, finTextureCoordinates);
if (texelColor.a == 0.0f) {
vec4 texelColor1 = getTexture(finTextureIndex1, finTextureCoordinates1);
if (texelColor1.a == 0.0f) {
discard;
}
outColor = texelColor * finTintColor;
if (finInterpolation == 0.0f) {
foutColor = texelColor1 * finTintColor;
return;
}
vec4 texelColor2 = getTexture(finTextureIndex2, finTextureCoordinates2);
if (texelColor2.a == 0.0f) {
discard;
}
foutColor = mix(texelColor1, texelColor2, finInterpolation) * finTintColor;
}

View File

@ -24,8 +24,11 @@ uniform vec3 uCameraUp;
in Vertex
{
uint textureIndex;
uint textureLayer;
uint textureIndex1;
uint textureLayer1;
uint textureIndex2;
uint textureLayer2;
float interpolation;
vec2 maxUVCoordinates;
float scale;
@ -33,8 +36,11 @@ in Vertex
} ginVertex[];
flat out uint finTextureIndex;
out vec3 finTextureCoordinates;
flat out uint finTextureIndex1;
out vec3 finTextureCoordinates1;
flat out uint finTextureIndex2;
out vec3 finTextureCoordinates2;
flat out float finInterpolation;
out vec4 finTintColor;
@ -43,24 +49,30 @@ void main()
vec3 pointPosition = gl_in[0].gl_Position.xyz;
finTextureIndex = ginVertex[0].textureIndex;
finTextureIndex1 = ginVertex[0].textureIndex1;
finTextureIndex2 = ginVertex[0].textureIndex2;
finInterpolation = ginVertex[0].interpolation;
finTintColor = ginVertex[0].tintColor;
gl_Position = uViewProjectionMatrix * vec4(pointPosition - (uCameraRight - uCameraUp) * ginVertex[0].scale, 1.0);
finTextureCoordinates = vec3(0.0f, ginVertex[0].maxUVCoordinates.y, ginVertex[0].textureLayer);
finTextureCoordinates1 = vec3(0.0f, 0.0f, ginVertex[0].textureLayer1);
finTextureCoordinates2 = vec3(0.0f, 0.0f, ginVertex[0].textureLayer2);
EmitVertex();
gl_Position = uViewProjectionMatrix * vec4(pointPosition - (uCameraRight + uCameraUp) * ginVertex[0].scale, 1.0);
finTextureCoordinates = vec3(0.0f, 0.0f, ginVertex[0].textureLayer);
finTextureCoordinates1 = vec3(0.0f, ginVertex[0].maxUVCoordinates.y, ginVertex[0].textureLayer1);
finTextureCoordinates2 = vec3(0.0f, ginVertex[0].maxUVCoordinates.y, ginVertex[0].textureLayer2);
EmitVertex();
gl_Position = uViewProjectionMatrix * vec4(pointPosition + (uCameraRight + uCameraUp) * ginVertex[0].scale, 1.0);
finTextureCoordinates = vec3(ginVertex[0].maxUVCoordinates, ginVertex[0].textureLayer);
finTextureCoordinates1 = vec3(ginVertex[0].maxUVCoordinates.x, 0.0f, ginVertex[0].textureLayer1);
finTextureCoordinates2 = vec3(ginVertex[0].maxUVCoordinates.x, 0.0f, ginVertex[0].textureLayer2);
EmitVertex();
gl_Position = uViewProjectionMatrix * vec4(pointPosition + (uCameraRight - uCameraUp) * ginVertex[0].scale, 1.0);
finTextureCoordinates = vec3(ginVertex[0].maxUVCoordinates.x, 0.0f, ginVertex[0].textureLayer);
finTextureCoordinates1 = vec3(ginVertex[0].maxUVCoordinates.x, ginVertex[0].maxUVCoordinates.y, ginVertex[0].textureLayer1);
finTextureCoordinates2 = vec3(ginVertex[0].maxUVCoordinates.x, ginVertex[0].maxUVCoordinates.y, ginVertex[0].textureLayer2);
EmitVertex();

View File

@ -16,15 +16,24 @@
layout (location = 0) in vec3 vinPosition;
layout (location = 1) in vec2 vinMaxUVCoordinates;
layout (location = 2) in uint vinTextureLayer;
layout (location = 3) in int vinAnimationIndex;
layout (location = 3) in float vinScale;
layout (location = 4) in uint vinTintColor;
layout (location = 4) in float vinScale;
layout (location = 5) in uint vinTintColor;
layout(std140) uniform AnimatedDataBuffer
{
uvec4 uAnimationData[ANIMATED_TEXTURE_COUNT];
};
out Vertex
{
uint textureIndex;
uint textureLayer;
uint textureIndex1;
uint textureLayer1;
uint textureIndex2;
uint textureLayer2;
float interpolation;
vec2 maxUVCoordinates;
float scale;
@ -36,10 +45,29 @@ out Vertex
void main() {
gl_Position = vec4(vinPosition, 1.0f);
ginVertex.textureIndex = vinTextureLayer >> 24u;
ginVertex.textureLayer = vinTextureLayer & 0xFFFFFFu;
ginVertex.maxUVCoordinates = vinMaxUVCoordinates;
ginVertex.scale = vinScale;
ginVertex.tintColor = getRGBAColor(vinTintColor);
if (vinAnimationIndex == -1) {
ginVertex.textureIndex1 = vinTextureLayer >> 24u;
ginVertex.textureLayer1 = vinTextureLayer & 0xFFFFFFu;
ginVertex.interpolation = 0.0f;
return;
}
uvec4 data = uAnimationData[vinAnimationIndex];
uint texture1 = data.x;
uint texture2 = data.y;
uint interpolation = data.z;
ginVertex.textureIndex1 = texture1 >> 24u;
ginVertex.textureLayer1 = texture1 & 0xFFFFFFu;
ginVertex.textureIndex2 = texture2 >> 24u;
ginVertex.textureLayer2 = texture2 & 0xFFFFFFu;
ginVertex.interpolation = interpolation / 100.0f;
}