diff --git a/doc/Shader.md b/doc/Shader.md
new file mode 100644
index 000000000..da83cd5cc
--- /dev/null
+++ b/doc/Shader.md
@@ -0,0 +1,15 @@
+# Shader
+
+## Variable declarations/naming
+
+All variables are prefixed with:
+
+- Vertex: `v`
+- Geometry: `g`
+- Fragment: `f`
+
+followed by `in`. So `vinPosition` is a valid name.
+
+## Uniforms
+
+Prefixed with u
diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockState.kt b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockState.kt
index fed97104a..70078c9b6 100644
--- a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockState.kt
+++ b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockState.kt
@@ -195,7 +195,7 @@ data class BlockState(
collisionShape = collisionShape,
occlusionShape = occlusionShape,
outlineShape = outlineShape,
- hardness = data["hardness"].asFloat,
+ hardness = data["hardness"]?.asFloat ?: 1.0f,
requiresTool = data["requires_tool"]?.asBoolean ?: material.soft,
breakSoundEvent = data["break_sound_type"]?.asInt?.let { registries.soundEventRegistry[it] },
stepSoundEvent = data["step_sound_type"]?.asInt?.let { registries.soundEventRegistry[it] },
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt
index 6e3680239..7f574d184 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderWindow.kt
@@ -25,6 +25,7 @@ import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLikeTexture
import de.bixilon.minosoft.gui.rendering.input.key.RenderWindowInputHandler
import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
+import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
import de.bixilon.minosoft.gui.rendering.textures.Texture
@@ -118,9 +119,11 @@ class RenderWindow(
}
})
+ // order dependant (from back to front)
registerRenderer(SkyRenderer)
registerRenderer(WorldRenderer)
registerRenderer(BlockOutlineRenderer)
+ registerRenderer(ParticleRenderer)
registerRenderer(HUDRenderer)
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/SectionArrayMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/SectionArrayMesh.kt
index a4c6ea467..93e2d4ed4 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/SectionArrayMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/SectionArrayMesh.kt
@@ -17,7 +17,7 @@ import de.bixilon.minosoft.data.text.ChatColors
import de.bixilon.minosoft.data.text.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.textures.Texture
-import de.bixilon.minosoft.gui.rendering.util.Mesh
+import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import glm_.vec2.Vec2
import glm_.vec3.Vec3
import org.lwjgl.opengl.GL11.GL_FLOAT
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/block/outline/BlockOutlineMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/block/outline/BlockOutlineMesh.kt
index 27a8b5f98..81cf426a1 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/block/outline/BlockOutlineMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/block/outline/BlockOutlineMesh.kt
@@ -13,7 +13,7 @@
package de.bixilon.minosoft.gui.rendering.chunk.block.outline
-import de.bixilon.minosoft.gui.rendering.util.Mesh
+import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import glm_.vec3.Vec3
import org.lwjgl.opengl.GL11.GL_FLOAT
import org.lwjgl.opengl.GL20.glEnableVertexAttribArray
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDMesh.kt
index fc39c0c51..45a45064b 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDMesh.kt
@@ -13,7 +13,7 @@
package de.bixilon.minosoft.gui.rendering.hud
-import de.bixilon.minosoft.gui.rendering.util.Mesh
+import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import org.lwjgl.opengl.GL11.GL_FLOAT
import org.lwjgl.opengl.GL20.glEnableVertexAttribArray
import org.lwjgl.opengl.GL20.glVertexAttribPointer
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt
new file mode 100644
index 000000000..7e5b31b00
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt
@@ -0,0 +1,72 @@
+/*
+ * 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.particle
+
+import de.bixilon.minosoft.data.text.RGBColor
+import de.bixilon.minosoft.gui.rendering.RenderConstants
+import de.bixilon.minosoft.gui.rendering.textures.Texture
+import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
+import glm_.vec3.Vec3
+import org.lwjgl.opengl.ARBVertexArrayObject.glBindVertexArray
+import org.lwjgl.opengl.GL11.*
+import org.lwjgl.opengl.GL20.glEnableVertexAttribArray
+import org.lwjgl.opengl.GL20.glVertexAttribPointer
+
+class ParticleMesh : Mesh() {
+
+ fun addVertex(position: Vec3, scale: Float, texture: Texture, tintColor: RGBColor) {
+ val textureLayer = if (RenderConstants.FORCE_DEBUG_TEXTURE) {
+ RenderConstants.DEBUG_TEXTURE_ID
+ } else {
+ (texture.arrayId shl 24) or texture.arrayLayer
+ }
+
+ data.addAll(floatArrayOf(
+ position.x,
+ position.y,
+ position.z,
+ texture.uvEnd.x,
+ texture.uvEnd.y,
+ Float.fromBits(textureLayer),
+ scale,
+ Float.fromBits(tintColor.rgba),
+ ))
+ }
+
+
+ override fun load() {
+ super.initializeBuffers(FLOATS_PER_VERTEX)
+ var index = 0
+ glVertexAttribPointer(index, 3, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, 0L)
+ glEnableVertexAttribArray(index++)
+ glVertexAttribPointer(index, 2, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, (3 * Float.SIZE_BYTES).toLong())
+ glEnableVertexAttribArray(index++)
+ glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, (5 * Float.SIZE_BYTES).toLong())
+ glEnableVertexAttribArray(index++)
+ glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, (6 * Float.SIZE_BYTES).toLong())
+ glEnableVertexAttribArray(index++)
+ glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.SIZE_BYTES, (7 * Float.SIZE_BYTES).toLong())
+ glEnableVertexAttribArray(index++)
+ super.unbind()
+ }
+
+ override fun draw() {
+ glBindVertexArray(vao)
+ glDrawArrays(GL_POINTS, 0, 1)
+ }
+
+ companion object {
+ private val FLOATS_PER_VERTEX = 8
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt
new file mode 100644
index 000000000..ade702e09
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt
@@ -0,0 +1,92 @@
+/*
+ * 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.particle
+
+import de.bixilon.minosoft.data.mappings.ResourceLocation
+import de.bixilon.minosoft.data.text.ChatColors
+import de.bixilon.minosoft.gui.rendering.RenderWindow
+import de.bixilon.minosoft.gui.rendering.Renderer
+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.modding.event.CallbackEventInvoker
+import de.bixilon.minosoft.protocol.network.connection.PlayConnection
+import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
+import glm_.vec3.Vec3
+
+
+class ParticleRenderer(
+ private val connection: PlayConnection,
+ val renderWindow: RenderWindow,
+) : Renderer {
+ private val particleShader = Shader(
+ resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "particle"),
+ )
+ private var particleMesh = ParticleMesh()
+
+ private val texture = Texture(DUMMY_PARTICLE_RESOURCE_LOCATION)
+
+ override fun init() {
+ particleShader.load()
+
+
+
+ particleMesh.load()
+
+ connection.registerEvent(CallbackEventInvoker.of {
+ renderWindow.queue += {
+ particleShader.use().setMat4("uViewProjectionMatrix", it.viewProjectionMatrix)
+ particleShader.use().setVec3("uCameraRight", Vec3(it.viewMatrix[0][0], it.viewMatrix[1][0], it.viewMatrix[2][0]))
+ particleShader.use().setVec3("uCameraUp", Vec3(it.viewMatrix[0][1], it.viewMatrix[1][1], it.viewMatrix[2][1]))
+ }
+ })
+ renderWindow.textures.allTextures += texture
+ }
+
+ override fun postInit() {
+ renderWindow.textures.use(particleShader, "textureArray")
+ }
+
+
+ override fun draw() {
+ particleShader.use()
+
+ 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)
+
+
+ particleMesh.load()
+
+ particleMesh.draw()
+ }
+
+ companion object : RendererBuilder {
+ override val RESOURCE_LOCATION = ResourceLocation("minosoft:particle")
+
+ private val DUMMY_PARTICLE_RESOURCE_LOCATION = ResourceLocation("minecraft:textures/particle/spark_4.png")
+
+
+ override fun build(connection: PlayConnection, renderWindow: RenderWindow): ParticleRenderer {
+ return ParticleRenderer(connection, renderWindow)
+ }
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/Shader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/shader/Shader.kt
index c807688ac..60772bfb1 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/Shader.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/shader/Shader.kt
@@ -155,7 +155,7 @@ class Shader(
companion object {
- private var currentShaderInUse: Shader? = null
+ private var currentShaderInUse: Shader? = null // ToDo: This is not safe todo
private fun createShader(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER, resourceLocation: ResourceLocation, shaderType: Int, defines: Map, uniforms: MutableList): Int? {
val shaderId = glCreateShaderObjectARB(shaderType)
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt
index 8e9e43cab..4d6e8a0d6 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyRenderer.kt
@@ -23,6 +23,7 @@ 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.util.mesh.SimpleTextureMesh
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
import de.bixilon.minosoft.modding.event.events.TimeChangeEvent
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
@@ -46,7 +47,7 @@ class SkyRenderer(
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "sky/sun"),
)
private val skyboxMesh = SkyboxMesh()
- private var skySunMesh = SkySunMesh()
+ private var skySunMesh = SimpleTextureMesh()
private var sunTexture = Texture(SUN_TEXTURE_RESOURCE_LOCATION)
private var recalculateSunNextFrame: Boolean = true
private var bottomColor = ChatColors.BLACK
@@ -95,7 +96,7 @@ class SkyRenderer(
setSunMatrix(renderWindow.inputHandler.camera.projectionMatrix * renderWindow.inputHandler.camera.viewMatrix.toMat3().toMat4())
skySunMesh.unload()
- skySunMesh = SkySunMesh()
+ skySunMesh = SimpleTextureMesh()
fun addQuad(start: Vec3, end: Vec3, texture: Texture, tintColor: RGBColor) {
skySunMesh.addVertex(Vec3(start.x, start.y, start.z), texture, Vec2(0.0, 0.0), tintColor)
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyboxMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyboxMesh.kt
index fa74b80c1..5ca0c48e3 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyboxMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkyboxMesh.kt
@@ -13,7 +13,7 @@
package de.bixilon.minosoft.gui.rendering.sky
-import de.bixilon.minosoft.gui.rendering.util.Mesh
+import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import org.lwjgl.opengl.GL11.GL_FLOAT
import org.lwjgl.opengl.GL20.glEnableVertexAttribArray
import org.lwjgl.opengl.GL20.glVertexAttribPointer
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureArray.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureArray.kt
index ac0d479b1..162f0ff9f 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureArray.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureArray.kt
@@ -132,7 +132,7 @@ class TextureArray(val allTextures: MutableList) {
var lastSize = texture.size
for (i in 0 until MAX_MIPMAP_LEVELS) {
val size = Vec2i(texture.size.x shr i, texture.size.y shr i)
- if (i != 0) {
+ if (i != 0 && size.x != 0 && size.y != 0) {
lastBuffer = generateMipmap(lastBuffer, lastSize, size)
lastSize = size
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/Mesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/Mesh.kt
similarity index 98%
rename from src/main/java/de/bixilon/minosoft/gui/rendering/util/Mesh.kt
rename to src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/Mesh.kt
index 5af9b7a0f..3a2780eb0 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/Mesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/Mesh.kt
@@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
-package de.bixilon.minosoft.gui.rendering.util
+package de.bixilon.minosoft.gui.rendering.util.mesh
import de.bixilon.minosoft.util.collections.ArrayFloatList
import org.lwjgl.opengl.GL11.GL_TRIANGLES
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkySunMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/SimpleTextureMesh.kt
similarity index 93%
rename from src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkySunMesh.kt
rename to src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/SimpleTextureMesh.kt
index 66411c9ea..1a8a9deb7 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/SkySunMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/SimpleTextureMesh.kt
@@ -11,19 +11,18 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
-package de.bixilon.minosoft.gui.rendering.sky
+package de.bixilon.minosoft.gui.rendering.util.mesh
import de.bixilon.minosoft.data.text.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.textures.Texture
-import de.bixilon.minosoft.gui.rendering.util.Mesh
import glm_.vec2.Vec2
import glm_.vec3.Vec3
import org.lwjgl.opengl.GL11.GL_FLOAT
import org.lwjgl.opengl.GL20.glEnableVertexAttribArray
import org.lwjgl.opengl.GL20.glVertexAttribPointer
-class SkySunMesh : Mesh(initialCacheSize = 2 * 3 * FLOATS_PER_VERTEX) {
+open class SimpleTextureMesh : Mesh(initialCacheSize = 2 * 3 * FLOATS_PER_VERTEX) {
fun addVertex(position: Vec3, texture: Texture, textureCoordinates: Vec2, tintColor: RGBColor) {
val textureLayer = if (RenderConstants.FORCE_DEBUG_TEXTURE) {
diff --git a/src/main/java/de/bixilon/minosoft/util/KUtil.kt b/src/main/java/de/bixilon/minosoft/util/KUtil.kt
index 76ef68e51..ed1d0cc20 100644
--- a/src/main/java/de/bixilon/minosoft/util/KUtil.kt
+++ b/src/main/java/de/bixilon/minosoft/util/KUtil.kt
@@ -15,6 +15,7 @@ package de.bixilon.minosoft.util
import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.util.enum.AliasableEnum
+import sun.misc.Unsafe
import java.util.*
import kotlin.Pair
@@ -100,4 +101,11 @@ object KUtil {
fun pause() {
var setBreakPointHere = 1
}
+
+ fun hardCrash() {
+ val field = Unsafe::class.java.getDeclaredField("theUnsafe")
+ field.isAccessible = true
+ val unsafe = field[null] as Unsafe
+ unsafe.putAddress(0, 0)
+ }
}
diff --git a/src/main/resources/assets/minosoft/rendering/shader/includes/color.glsl b/src/main/resources/assets/minosoft/rendering/shader/includes/color.glsl
index 51e0bf9bb..08a44612c 100644
--- a/src/main/resources/assets/minosoft/rendering/shader/includes/color.glsl
+++ b/src/main/resources/assets/minosoft/rendering/shader/includes/color.glsl
@@ -13,8 +13,8 @@
vec4 getRGBColor(uint color) {
- return vec4(((tintColor >> 16u) & 0xFFu) / 255.0f, ((tintColor >> 8u) & 0xFFu) / 255.0f, (tintColor & 0xFFu) / 255.0f, 1.0f);
+ return vec4(((color >> 16u) & 0xFFu) / 255.0f, ((color >> 8u) & 0xFFu) / 255.0f, (color & 0xFFu) / 255.0f, 1.0f);
}
vec4 getRGBAColor(uint color) {
- return vec4(((tintColor >> 24u) & 0xFFu) / 255.0f, ((tintColor >> 16u) & 0xFFu) / 255.0f, ((tintColor >> 8u) & 0xFFu) / 255.0f, (tintColor & 0xFFu) / 255.0f);
+ return vec4(((color >> 24u) & 0xFFu) / 255.0f, ((color >> 16u) & 0xFFu) / 255.0f, ((color >> 8u) & 0xFFu) / 255.0f, (color & 0xFFu) / 255.0f);
}
diff --git a/src/main/resources/assets/minosoft/rendering/shader/particle/particle.fsh b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.fsh
new file mode 100644
index 000000000..de655ba1c
--- /dev/null
+++ b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.fsh
@@ -0,0 +1,32 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+#version 330 core
+
+out vec4 outColor;
+
+flat in uint finTextureIndex;
+in vec3 finTextureCoordinates;
+
+in vec4 finTintColor;
+
+#include "minosoft:texture"
+
+void main() {
+ vec4 texelColor = getTexture(finTextureIndex, finTextureCoordinates);
+ if (texelColor.a == 0.0f) {
+ discard;
+ }
+
+ outColor = texelColor * finTintColor;
+}
diff --git a/src/main/resources/assets/minosoft/rendering/shader/particle/particle.gsh b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.gsh
new file mode 100644
index 000000000..b3e70c14f
--- /dev/null
+++ b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.gsh
@@ -0,0 +1,68 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+#version 330
+
+layout (points) in;
+layout (triangle_strip) out;
+layout (max_vertices = 4) out;
+
+uniform mat4 uViewProjectionMatrix;
+uniform vec3 uCameraRight;
+uniform vec3 uCameraUp;
+
+
+in Vertex
+{
+ uint textureIndex;
+ uint textureLayer;
+ vec2 maxUVCoordinates;
+
+ float scale;
+ vec4 tintColor;
+} ginVertex[];
+
+
+flat out uint finTextureIndex;
+out vec3 finTextureCoordinates;
+
+out vec4 finTintColor;
+
+void main()
+{
+ vec3 pointPosition = gl_in[0].gl_Position.xyz;
+
+
+ finTextureIndex = ginVertex[0].textureIndex;
+ 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);
+ EmitVertex();
+
+ gl_Position = uViewProjectionMatrix * vec4(pointPosition - (uCameraRight + uCameraUp) * ginVertex[0].scale, 1.0);
+ finTextureCoordinates = vec3(0.0f, 0.0f, ginVertex[0].textureLayer);
+ EmitVertex();
+
+ gl_Position = uViewProjectionMatrix * vec4(pointPosition + (uCameraRight + uCameraUp) * ginVertex[0].scale, 1.0);
+ finTextureCoordinates = vec3(ginVertex[0].maxUVCoordinates, ginVertex[0].textureLayer);
+ EmitVertex();
+
+ gl_Position = uViewProjectionMatrix * vec4(pointPosition + (uCameraRight - uCameraUp) * ginVertex[0].scale, 1.0);
+ finTextureCoordinates = vec3(ginVertex[0].maxUVCoordinates.x, 0.0f, ginVertex[0].textureLayer);
+ EmitVertex();
+
+
+ EndPrimitive();
+}
diff --git a/src/main/resources/assets/minosoft/rendering/shader/particle/particle.vsh b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.vsh
new file mode 100644
index 000000000..49c7a5e57
--- /dev/null
+++ b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.vsh
@@ -0,0 +1,45 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020 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 .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+#version 330 core
+
+layout (location = 0) in vec3 vinPosition;
+layout (location = 1) in vec2 vinMaxUVCoordinates;
+layout (location = 2) in uint vinTextureLayer;
+
+layout (location = 3) in float vinScale;
+layout (location = 4) in uint vinTintColor;
+
+
+out Vertex
+{
+ uint textureIndex;
+ uint textureLayer;
+ vec2 maxUVCoordinates;
+
+ float scale;
+ vec4 tintColor;
+} ginVertex;
+
+#include "minosoft:color"
+
+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);
+}