rendering: shader: add geometry shaders, allow dynamic defines, animated textures: use correct count of animated textures

This commit is contained in:
Bixilon 2021-04-07 13:55:00 +02:00
parent 91241194a4
commit 283f390373
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
6 changed files with 62 additions and 49 deletions

View File

@ -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")

View File

@ -38,7 +38,10 @@ import glm_.vec2.Vec2i
class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow) : Renderer {
private val hudElements: MutableMap<ResourceLocation, Pair<HUDElementProperties, HUDElement>> = mutableMapOf()
private val enabledHUDElement: MutableMap<ResourceLocation, Pair<HUDElementProperties, HUDElement>> = 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<ResourceLocation, HUDAtlasElement>
var orthographicMatrix: Mat4 = Mat4()
private set

View File

@ -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<String, Any> = 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<String, Any>): 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
}
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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
}
}

View File

@ -161,7 +161,7 @@ class TextureArray(val allTextures: MutableList<Texture>) {
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()

View File

@ -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??
};