mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 17:37:58 -04:00
particle texture (sprite) animations
This commit is contained in:
parent
f138cfe709
commit
70c9986acc
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user