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.x,
texture.uvEnd.y, texture.uvEnd.y,
Float.fromBits(textureLayer), Float.fromBits(textureLayer),
Float.fromBits(texture.properties.animation?.animationId ?: -1),
scale, scale,
Float.fromBits(tintColor.rgba), Float.fromBits(tintColor.rgba),
)) ))
@ -58,15 +59,17 @@ class ParticleMesh : Mesh() {
glEnableVertexAttribArray(index++) glEnableVertexAttribArray(index++)
glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, (7 * Float.SIZE_BYTES).toLong()) glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, (7 * Float.SIZE_BYTES).toLong())
glEnableVertexAttribArray(index++) glEnableVertexAttribArray(index++)
glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, (8 * Float.SIZE_BYTES).toLong())
glEnableVertexAttribArray(index++)
super.unbind() super.unbind()
} }
override fun draw() { override fun draw() {
glBindVertexArray(vao) glBindVertexArray(vao)
glDrawArrays(GL_POINTS, 0, 1) glDrawArrays(GL_POINTS, 0, primitiveCount)
} }
companion object { 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.modding.events.CameraMatrixChangeEvent
import de.bixilon.minosoft.gui.rendering.shader.Shader import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.textures.Texture 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.modding.event.CallbackEventInvoker
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.MMath
import glm_.vec3.Vec3 import glm_.vec3.Vec3
import java.util.concurrent.ThreadLocalRandom
class ParticleRenderer( class ParticleRenderer(
private val connection: PlayConnection, private val connection: PlayConnection,
val renderWindow: RenderWindow, val renderWindow: RenderWindow,
) : Renderer { ) : Renderer {
private val particleShader = Shader( private lateinit var particleShader: Shader
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "particle"),
)
private var particleMesh = ParticleMesh() private var particleMesh = ParticleMesh()
private val texture = Texture(DUMMY_PARTICLE_RESOURCE_LOCATION) private val texture = Texture(DUMMY_PARTICLE_RESOURCE_LOCATION)
override fun init() { override fun init() {
particleShader.load()
@ -56,25 +56,39 @@ class ParticleRenderer(
} }
override fun postInit() { 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.use(particleShader, "textureArray")
renderWindow.textures.animator.use(particleShader, "AnimatedDataBuffer")
} }
var last = 0L
override fun draw() { override fun draw() {
particleShader.use() particleShader.use()
val time = System.currentTimeMillis()
if (time - last >= ProtocolDefinition.TICK_TIME * 2000) {
particleMesh.unload() particleMesh.unload()
particleMesh = ParticleMesh() particleMesh = ParticleMesh()
// thanks: https://gamedev.stackexchange.com/questions/113147/rotate-billboard-towards-camera
val position = Vec3(0, 6, 0)
val random = ThreadLocalRandom.current()
particleMesh.addVertex(position, 1.0f, texture, ChatColors.RED) 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() particleMesh.load()
last = time
}
particleMesh.draw() particleMesh.draw()
} }

View File

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

View File

@ -13,20 +13,34 @@
#version 330 core #version 330 core
out vec4 outColor; out vec4 foutColor;
flat in uint finTextureIndex; flat in uint finTextureIndex1;
in vec3 finTextureCoordinates; in vec3 finTextureCoordinates1;
flat in uint finTextureIndex2;
in vec3 finTextureCoordinates2;
flat in float finInterpolation;
in vec4 finTintColor; in vec4 finTintColor;
#include "minosoft:texture" #include "minosoft:texture"
void main() { void main() {
vec4 texelColor = getTexture(finTextureIndex, finTextureCoordinates); vec4 texelColor1 = getTexture(finTextureIndex1, finTextureCoordinates1);
if (texelColor.a == 0.0f) { if (texelColor1.a == 0.0f) {
discard; 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 in Vertex
{ {
uint textureIndex; uint textureIndex1;
uint textureLayer; uint textureLayer1;
uint textureIndex2;
uint textureLayer2;
float interpolation;
vec2 maxUVCoordinates; vec2 maxUVCoordinates;
float scale; float scale;
@ -33,8 +36,11 @@ in Vertex
} ginVertex[]; } ginVertex[];
flat out uint finTextureIndex; flat out uint finTextureIndex1;
out vec3 finTextureCoordinates; out vec3 finTextureCoordinates1;
flat out uint finTextureIndex2;
out vec3 finTextureCoordinates2;
flat out float finInterpolation;
out vec4 finTintColor; out vec4 finTintColor;
@ -43,24 +49,30 @@ void main()
vec3 pointPosition = gl_in[0].gl_Position.xyz; 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; finTintColor = ginVertex[0].tintColor;
gl_Position = uViewProjectionMatrix * vec4(pointPosition - (uCameraRight - uCameraUp) * ginVertex[0].scale, 1.0); 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(); EmitVertex();
gl_Position = uViewProjectionMatrix * vec4(pointPosition - (uCameraRight + uCameraUp) * ginVertex[0].scale, 1.0); 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(); EmitVertex();
gl_Position = uViewProjectionMatrix * vec4(pointPosition + (uCameraRight + uCameraUp) * ginVertex[0].scale, 1.0); 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(); EmitVertex();
gl_Position = uViewProjectionMatrix * vec4(pointPosition + (uCameraRight - uCameraUp) * ginVertex[0].scale, 1.0); 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(); EmitVertex();

View File

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