diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/MinosoftShader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/shader/MinosoftShader.kt
new file mode 100644
index 000000000..7d04536d7
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/shader/MinosoftShader.kt
@@ -0,0 +1,49 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2022 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.shader
+
+import de.bixilon.minosoft.gui.rendering.shader.uniform.ShaderUniform
+import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader
+import kotlin.reflect.KFunction3
+
+abstract class MinosoftShader {
+ private val uniforms: MutableMap> = mutableMapOf()
+ abstract val native: Shader
+
+ fun load() {
+ native.load()
+ }
+
+ fun postLoad() {
+ for (uniform in uniforms.values) {
+ uniform.upload()
+ }
+ }
+
+ fun use() {
+ native.use()
+ }
+
+
+ fun uniform(name: String, default: T, type: KFunction3 = Shader::set): ShaderUniform {
+ val uniform = ShaderUniform(native, default, name, type)
+ val previous = uniforms.put(name, uniform)
+
+ if (previous != null) {
+ throw IllegalStateException("Duplicated uniform: $name")
+ }
+
+ return uniform
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/uniform/ShaderUniform.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/shader/uniform/ShaderUniform.kt
new file mode 100644
index 000000000..5148bd62b
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/shader/uniform/ShaderUniform.kt
@@ -0,0 +1,54 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2022 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.shader.uniform
+
+import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader
+import kotlin.properties.ReadWriteProperty
+import kotlin.reflect.KFunction3
+import kotlin.reflect.KProperty
+
+class ShaderUniform(
+ private val native: Shader,
+ default: T,
+ private val name: String,
+ private val setter: KFunction3,
+) : ReadWriteProperty {
+ private var value = default
+ private var upload: Boolean = true
+
+ fun upload() {
+ if (!upload) {
+ return
+ }
+ native.use()
+ setter(native, name, value)
+ upload = false
+ }
+
+ override fun getValue(thisRef: Any, property: KProperty<*>): T {
+ return value
+ }
+
+ override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
+ if (this.value == value) {
+ return
+ }
+ this.value = value
+ upload = true
+ if (Thread.currentThread() == native.renderWindow.thread) {
+ upload()
+ }
+ }
+
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/planet/PlanetRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/planet/PlanetRenderer.kt
index cdb06229b..d43e0d833 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/planet/PlanetRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/planet/PlanetRenderer.kt
@@ -31,7 +31,7 @@ abstract class PlanetRenderer(
protected val sky: SkyRenderer,
) : SkyChildRenderer {
protected abstract val texture: AbstractTexture
- protected val shader = sky.renderWindow.renderSystem.createShader(minosoft("sky/planet"))
+ protected val shader = sky.renderWindow.renderSystem.createShader(minosoft("sky/planet")) { PlanetShader(it) }
private var mesh = PlanetMesh(sky.renderWindow)
protected var day = -1L
protected var matrix = Mat4()
@@ -69,6 +69,7 @@ abstract class PlanetRenderer(
override fun postInit() {
prepareMesh()
+ shader.postLoad()
sky.renderWindow.textureManager.staticTextures.use(shader)
sky::matrix.observe(this) { calculateMatrix(it) }
}
@@ -108,11 +109,11 @@ abstract class PlanetRenderer(
}
shader.use()
if (matrixUpdate) {
- shader.setMat4("uMatrix", matrix)
+ shader.matrix = matrix
val intensity = calculateIntensity()
if (this.intensity != intensity) {
- shader.setVec4("uTintColor", Vec4(1.0f, 1.0f, 1.0f, intensity))
+ shader.tintColor = Vec4(1.0f, 1.0f, 1.0f, intensity)
this.intensity = intensity
}
this.matrixUpdate = false
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/sky/planet/PlanetShader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/planet/PlanetShader.kt
new file mode 100644
index 000000000..d78ad3f4d
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/sky/planet/PlanetShader.kt
@@ -0,0 +1,26 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2022 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.sky.planet
+
+import de.bixilon.kotlinglm.mat4x4.Mat4
+import de.bixilon.kotlinglm.vec4.Vec4
+import de.bixilon.minosoft.gui.rendering.shader.MinosoftShader
+import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader
+
+class PlanetShader(
+ override val native: Shader,
+) : MinosoftShader() {
+ var matrix: Mat4 by uniform("uMatrix", Mat4())
+ var tintColor: Vec4 by uniform("uTintColor", Vec4())
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt
index 715ccad07..edbbd50d9 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt
@@ -18,6 +18,7 @@ import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.text.formatting.color.Colors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderWindow
+import de.bixilon.minosoft.gui.rendering.shader.MinosoftShader
import de.bixilon.minosoft.gui.rendering.system.base.buffer.frame.Framebuffer
import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.FloatUniformBuffer
import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.IntUniformBuffer
@@ -108,6 +109,10 @@ interface RenderSystem {
)
}
+ fun createShader(resourceLocation: ResourceLocation, creator: (native: Shader) -> T): T {
+ return creator(createShader(resourceLocation))
+ }
+
fun createShader(vertex: ResourceLocation, geometry: ResourceLocation? = null, fragment: ResourceLocation): Shader
fun createVertexBuffer(structure: MeshStruct, data: FloatBuffer, primitiveType: PrimitiveTypes = preferredPrimitiveType): FloatVertexBuffer
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureArray.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureArray.kt
index b86c70b28..fb9792ab2 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureArray.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureArray.kt
@@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.system.base.texture
import de.bixilon.kutil.latch.CountUpAndDownLatch
+import de.bixilon.minosoft.gui.rendering.shader.MinosoftShader
import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader
import de.bixilon.minosoft.gui.rendering.system.base.shader.ShaderUniforms
@@ -21,5 +22,8 @@ interface TextureArray {
fun load(latch: CountUpAndDownLatch)
fun activate()
+
+ @Deprecated("safe uniforms")
fun use(shader: Shader, name: String = ShaderUniforms.TEXTURES)
+ fun use(shader: MinosoftShader) = use(shader.native)
}