diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt index 3d0b709fd..cde8a6b58 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt @@ -95,9 +95,6 @@ class WorldRenderer( renderWindow.textures.allTextures.addAll(resolveBlockTextureIds(connection.version.mapping.blockStateIdMap.values)) - chunkShader = Shader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/chunk_vertex.glsl"), ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/chunk_fragment.glsl")) - chunkShader.load() - // register keybindings renderWindow.registerKeyCallback(KeyBindingsNames.DEBUG_CLEAR_CHUNK_CACHE) { _, _ -> clearChunkCache() @@ -107,6 +104,14 @@ class WorldRenderer( } override fun postInit() { + check(renderWindow.textures.animator.animatedTextures.size < 4096) { "Can not have more than 4096 animated textures!" } // uniform buffer limit: 16kb. 4 ints per texture + chunkShader = Shader( + vertexPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/chunk_vertex.glsl"), + fragmentPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/chunk_fragment.glsl"), + defines = mapOf("ANIMATED_TEXTURE_COUNT" to renderWindow.textures.animator.animatedTextures.size), + ) + chunkShader.load() + renderWindow.textures.use(chunkShader, "textureArray") renderWindow.textures.animator.use(chunkShader, "AnimatedDataBuffer") diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt index ee42b9a28..0b9e24378 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/HUDRenderer.kt @@ -38,7 +38,10 @@ import glm_.vec2.Vec2i class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow) : Renderer { private val hudElements: MutableMap> = mutableMapOf() private val enabledHUDElement: MutableMap> = mutableMapOf() - private val hudShader = Shader(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_vertex.glsl"), ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_fragment.glsl")) + private val hudShader = Shader( + vertexPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_vertex.glsl"), + fragmentPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_fragment.glsl"), + ) lateinit var hudAtlasElements: Map var orthographicMatrix: Mat4 = Mat4() private set 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 26292aa69..536b0bbbf 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 @@ -24,6 +24,7 @@ import glm_.vec3.Vec3 import glm_.vec4.Vec4 import org.lwjgl.BufferUtils import org.lwjgl.opengl.ARBFragmentShader.GL_FRAGMENT_SHADER_ARB +import org.lwjgl.opengl.ARBGeometryShader4.GL_GEOMETRY_SHADER_ARB import org.lwjgl.opengl.ARBShaderObjects.* import org.lwjgl.opengl.ARBVertexShader.GL_VERTEX_SHADER_ARB import org.lwjgl.opengl.GL11.GL_FALSE @@ -32,13 +33,16 @@ import org.lwjgl.system.MemoryUtil class Shader( private val vertexPath: ResourceLocation, + private val geometryPath: ResourceLocation? = null, private val fragmentPath: ResourceLocation, + private val defines: Map = mapOf(), ) { private var programId = 0 fun load(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER): Int { - val vertexShader = ShaderUtil.createShader(assetsManager, vertexPath, GL_VERTEX_SHADER_ARB) - val fragmentShader = ShaderUtil.createShader(assetsManager, fragmentPath, GL_FRAGMENT_SHADER_ARB) + val vertexShader = createShader(assetsManager, vertexPath, GL_VERTEX_SHADER_ARB, defines) + val geometryShader = geometryPath?.let { createShader(assetsManager, it, GL_GEOMETRY_SHADER_ARB, defines) } + val fragmentShader = createShader(assetsManager, fragmentPath, GL_FRAGMENT_SHADER_ARB, defines) programId = glCreateProgramObjectARB() if (programId.toLong() == MemoryUtil.NULL) { @@ -46,6 +50,9 @@ class Shader( } glAttachObjectARB(programId, vertexShader) + geometryShader?.let { + glAttachObjectARB(programId, it) + } glAttachObjectARB(programId, fragmentShader) glLinkProgramARB(programId) @@ -59,6 +66,9 @@ class Shader( throw ShaderLoadingException(OpenGLUtil.getLogInfo(programId)) } glDeleteShader(vertexShader) + geometryShader?.let { + glDeleteShader(it) + } glDeleteShader(fragmentShader) return programId @@ -133,5 +143,41 @@ class Shader( companion object { private var usedShader: Shader? = null + + + private fun createShader(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER, resourceLocation: ResourceLocation, shaderType: Int, defines: Map): Int { + val shaderId = glCreateShaderObjectARB(shaderType) + if (shaderId.toLong() == MemoryUtil.NULL) { + throw ShaderLoadingException() + } + val total = StringBuilder() + val lines = assetsManager.readStringAsset(resourceLocation).lines() + + for (line in lines) { + total.append(line) + total.append('\n') + if (line.startsWith("#version")) { + + // add all defines + total.append('\n') + for ((define, value) in defines) { + total.append("#define ") + total.append(define) + total.append(' ') + total.append(value) + total.append('\n') + } + } + } + + glShaderSourceARB(shaderId, total.toString()) + glCompileShaderARB(shaderId) + + if (glGetObjectParameteriARB(shaderId, GL_OBJECT_COMPILE_STATUS_ARB) == GL_FALSE) { + throw ShaderLoadingException(OpenGLUtil.getLogInfo(shaderId)) + } + + return shaderId + } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/ShaderUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/shader/ShaderUtil.kt deleted file mode 100644 index d226090c1..000000000 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/shader/ShaderUtil.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - */ - -package de.bixilon.minosoft.gui.rendering.shader - -import de.bixilon.minosoft.Minosoft -import de.bixilon.minosoft.data.assets.AssetsManager -import de.bixilon.minosoft.data.mappings.ResourceLocation -import de.bixilon.minosoft.gui.rendering.exceptions.ShaderLoadingException -import de.bixilon.minosoft.gui.rendering.util.OpenGLUtil -import org.lwjgl.opengl.ARBShaderObjects.* -import org.lwjgl.opengl.GL11.GL_FALSE -import org.lwjgl.system.MemoryUtil - -object ShaderUtil { - fun createShader(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER, resourceLocation: ResourceLocation, shaderType: Int): Int { - val shaderId = glCreateShaderObjectARB(shaderType) - if (shaderId.toLong() == MemoryUtil.NULL) { - throw ShaderLoadingException() - } - - glShaderSourceARB(shaderId, assetsManager.readStringAsset(resourceLocation)) - glCompileShaderARB(shaderId) - - if (glGetObjectParameteriARB(shaderId, GL_OBJECT_COMPILE_STATUS_ARB) == GL_FALSE) { - throw ShaderLoadingException(OpenGLUtil.getLogInfo(shaderId)) - } - - return shaderId - } -} 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 026fcd949..7be98f0cf 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 @@ -161,7 +161,7 @@ class TextureArray(val allTextures: MutableList) { private set fun initBuffer() { - animatedData = IntArray(128 * INTS_PER_ANIMATED_TEXTURE) // 4 data ints per entry + animatedData = IntArray(animatedTextures.size * INTS_PER_ANIMATED_TEXTURE) // 4 data ints per entry animatedBufferDataId = glGenBuffers() diff --git a/src/main/resources/assets/minosoft/rendering/shader/chunk_vertex.glsl b/src/main/resources/assets/minosoft/rendering/shader/chunk_vertex.glsl index 3a4ba85f8..57819cf6c 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/chunk_vertex.glsl +++ b/src/main/resources/assets/minosoft/rendering/shader/chunk_vertex.glsl @@ -33,7 +33,7 @@ uniform mat4 viewProjectionMatrix; layout(std140) uniform AnimatedDataBuffer { - uvec4 globalAnimationData[128];// ToDo: WTF. Why 4 values?? + uvec4 globalAnimationData[ANIMATED_TEXTURE_COUNT];// ToDo: WTF. Why 4 values?? };