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) }