From f29b15d95b17103f6d94088bfa7437607b06938d Mon Sep 17 00:00:00 2001 From: Bixilon Date: Mon, 15 Feb 2021 17:15:45 +0100 Subject: [PATCH] rendering: shader: improvements, reduce gpu load and vram usage --- .../de/bixilon/minosoft/data/text/RGBColor.java | 2 +- .../bixilon/minosoft/data/text/TextComponent.kt | 7 ++----- .../bixilon/minosoft/gui/rendering/Rendering.kt | 1 + .../gui/rendering/chunk/ChunkRenderer.kt | 4 ++-- .../minosoft/gui/rendering/chunk/WorldMesh.kt | 16 +++++++++------- .../gui/rendering/chunk/models/BlockModel.kt | 5 ++--- .../rendering/hud/elements/text/HUDFontMesh.kt | 14 +++++++++----- .../hud/elements/text/HUDTextElement.kt | 8 +++----- .../assets/rendering/shader/chunk_vertex.glsl | 3 +-- .../assets/rendering/shader/font_vertex.glsl | 7 ++++--- 10 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/text/RGBColor.java b/src/main/java/de/bixilon/minosoft/data/text/RGBColor.java index 40363c6fd..64349e96f 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/RGBColor.java +++ b/src/main/java/de/bixilon/minosoft/data/text/RGBColor.java @@ -77,7 +77,7 @@ public final class RGBColor implements ChatCode { @Override public String toString() { - if (getAlpha() > 0) { + if (getAlpha() != 255) { return String.format("#%08X", this.color); } return String.format("#%06X", (0xFFFFFF & this.color)); diff --git a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt index 0c43383bf..6e3ab593f 100644 --- a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt +++ b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.kt @@ -210,11 +210,8 @@ open class TextComponent : ChatComponent { meshData.add(-0.997f) meshData.add(uv.x) meshData.add(uv.y) - meshData.add(atlasPage.toFloat()) - meshData.add(color.red / 256f) - meshData.add(color.green / 256f) - meshData.add(color.blue / 256f) - meshData.add(1f) + meshData.add(Float.fromBits(atlasPage)) + meshData.add(Float.fromBits(color.color)) } fun drawLetter(position: Vec2, scaledWidth: Float, scaledHeight: Float, fontChar: FontChar, color: RGBColor, meshData: MutableList) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt index c4cabc284..05bfdacd0 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/Rendering.kt @@ -22,6 +22,7 @@ class Rendering(private val connection: Connection) { renderWindow.startRenderLoop() renderWindow.exit() } catch (exception: Throwable) { + exception.printStackTrace() if (connection.isConnected) { connection.disconnect() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkRenderer.kt index 23a877622..f99261b74 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/ChunkRenderer.kt @@ -74,7 +74,7 @@ class ChunkRenderer(private val connection: Connection, private val world: World // continue // } - block.getBlockModel(BlockPosition(chunkLocation, sectionHeight, position)).render(position, data, arrayOf(blockBelow, blockAbove, blockNorth, blockSouth, blockWest, blockEast)) + block.getBlockModel(BlockPosition(chunkLocation, sectionHeight, position)).render(Vec3(position.x + chunkLocation.x * ProtocolDefinition.SECTION_WIDTH_X, position.y + sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y, position.z + chunkLocation.z * ProtocolDefinition.SECTION_WIDTH_Z), data, arrayOf(blockBelow, blockAbove, blockNorth, blockSouth, blockWest, blockEast)) } return data.toFloatArray() } @@ -129,7 +129,7 @@ class ChunkRenderer(private val connection: Connection, private val world: World val data = prepareChunk(chunkLocation, sectionHeight, section) val sectionMap = chunkSectionsToDraw[chunkLocation]!! renderWindow.renderQueue.add { - val newMesh = WorldMesh(data, Vec3(chunkLocation.x, sectionHeight, chunkLocation.z)) + val newMesh = WorldMesh(data) sectionMap[sectionHeight]?.unload() sectionMap[sectionHeight] = newMesh } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldMesh.kt index 42521b917..2b2b1cba5 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldMesh.kt @@ -2,27 +2,26 @@ package de.bixilon.minosoft.gui.rendering.chunk import de.bixilon.minosoft.gui.rendering.shader.Shader import glm_.BYTES -import glm_.vec3.Vec3 import org.lwjgl.opengl.GL11.GL_FLOAT import org.lwjgl.opengl.GL20.glEnableVertexAttribArray import org.lwjgl.opengl.GL20.glVertexAttribPointer import org.lwjgl.opengl.GL30.* -class WorldMesh(data: FloatArray, var worldPosition: Vec3) { +class WorldMesh(data: FloatArray) { var vAO: Int = glGenVertexArrays() var vBO: Int = glGenBuffers() - var trianglesCount: Int = data.size / 6 // <- bytes per vertex + var trianglesCount: Int = data.size / BYTES_PER_VERTEX init { // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). glBindVertexArray(vAO) glBindBuffer(GL_ARRAY_BUFFER, vBO) glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW) - glVertexAttribPointer(0, 3, GL_FLOAT, false, 6 * Float.BYTES, 0L) + glVertexAttribPointer(0, 3, GL_FLOAT, false, BYTES_PER_VERTEX * Float.BYTES, 0L) glEnableVertexAttribArray(0) - glVertexAttribPointer(1, 2, GL_FLOAT, false, 6 * Float.BYTES, (3 * Float.BYTES).toLong()) + glVertexAttribPointer(1, 2, GL_FLOAT, false, BYTES_PER_VERTEX * Float.BYTES, (3 * Float.BYTES).toLong()) glEnableVertexAttribArray(1) - glVertexAttribPointer(2, 1, GL_FLOAT, false, 6 * Float.BYTES, (5 * Float.BYTES).toLong()) + glVertexAttribPointer(2, 1, GL_FLOAT, false, BYTES_PER_VERTEX * Float.BYTES, (5 * Float.BYTES).toLong()) glEnableVertexAttribArray(2) // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind @@ -30,7 +29,6 @@ class WorldMesh(data: FloatArray, var worldPosition: Vec3) { } fun draw(chunkShader: Shader) { - chunkShader.setVec3("worldPosition", worldPosition) glBindVertexArray(vAO) glDrawArrays(GL_TRIANGLES, 0, trianglesCount) } @@ -39,4 +37,8 @@ class WorldMesh(data: FloatArray, var worldPosition: Vec3) { glDeleteVertexArrays(vAO) glDeleteBuffers(vBO) } + + companion object { + private const val BYTES_PER_VERTEX = 6 + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/BlockModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/BlockModel.kt index 0f0a886b4..cd858217e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/BlockModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/BlockModel.kt @@ -3,7 +3,6 @@ package de.bixilon.minosoft.gui.rendering.chunk.models import com.google.gson.JsonObject import de.bixilon.minosoft.data.Directions import de.bixilon.minosoft.data.mappings.blocks.Block -import de.bixilon.minosoft.data.world.InChunkSectionLocation import de.bixilon.minosoft.gui.rendering.textures.Texture import glm_.glm import glm_.mat4x4.Mat4 @@ -56,8 +55,8 @@ open class BlockModel(val parent: BlockModel? = null, json: JsonObject) { } - open fun render(position: InChunkSectionLocation, data: MutableList, neighbourBlocks: Array) { - val modelMatrix = Mat4().translate(Vec3(position.x, position.y, position.z)) + open fun render(position: Vec3, data: MutableList, neighbourBlocks: Array) { + val modelMatrix = Mat4().translate(position) .rotate(rotation.z, Vec3(0, 0, -1)) .rotate(rotation.y, Vec3(0, -1, 0)) .rotate(rotation.x, Vec3(1, 0, 0)) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDFontMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDFontMesh.kt index c575c10a3..08c8ba4e6 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDFontMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDFontMesh.kt @@ -9,7 +9,7 @@ import org.lwjgl.opengl.GL30.* class HUDFontMesh(data: FloatArray) { var vAO: Int = glGenVertexArrays() var vBO: Int = glGenBuffers() - var trianglesCount: Int = data.size / 10 // <- bytes per vertex + var trianglesCount: Int = data.size / BYTES_PER_VERTEX fun draw() { glBindVertexArray(vAO) @@ -26,16 +26,20 @@ class HUDFontMesh(data: FloatArray) { glBindVertexArray(vAO) glBindBuffer(GL_ARRAY_BUFFER, vBO) glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW) - glVertexAttribPointer(0, 3, GL_FLOAT, false, 10 * Float.BYTES, 0L) + glVertexAttribPointer(0, 3, GL_FLOAT, false, BYTES_PER_VERTEX * Float.BYTES, 0L) glEnableVertexAttribArray(0) - glVertexAttribPointer(1, 2, GL_FLOAT, false, 10 * Float.BYTES, (3 * Float.BYTES).toLong()) + glVertexAttribPointer(1, 2, GL_FLOAT, false, BYTES_PER_VERTEX * Float.BYTES, (3 * Float.BYTES).toLong()) glEnableVertexAttribArray(1) - glVertexAttribPointer(2, 1, GL_FLOAT, false, 10 * Float.BYTES, (5 * Float.BYTES).toLong()) + glVertexAttribPointer(2, 1, GL_FLOAT, false, BYTES_PER_VERTEX * Float.BYTES, (5 * Float.BYTES).toLong()) glEnableVertexAttribArray(2) - glVertexAttribPointer(3, 4, GL_FLOAT, false, 10 * Float.BYTES, (6 * Float.BYTES).toLong()) + glVertexAttribPointer(3, 1, GL_FLOAT, false, BYTES_PER_VERTEX * Float.BYTES, (6 * Float.BYTES).toLong()) glEnableVertexAttribArray(3) // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind glBindBuffer(GL_ARRAY_BUFFER, 0) } + + companion object { + private const val BYTES_PER_VERTEX = 7 + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt index 77e7dadea..7b30b9820 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/hud/elements/text/HUDTextElement.kt @@ -2,6 +2,7 @@ package de.bixilon.minosoft.gui.rendering.hud.elements.text import de.bixilon.minosoft.data.mappings.ModIdentifier import de.bixilon.minosoft.data.text.ChatComponent +import de.bixilon.minosoft.data.text.RGBColor import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.font.Font import de.bixilon.minosoft.gui.rendering.font.FontBindings @@ -49,12 +50,9 @@ class HUDTextElement(val connection: Connection, val hudRenderer: HUDRenderer, v meshData.add(0f) meshData.add(0f) - meshData.add(0f) + meshData.add(Float.fromBits(0)) - meshData.add(0f) - meshData.add(0f) - meshData.add(0f) - meshData.add(0.3f) + meshData.add(Float.fromBits(RGBColor(0, 0, 0, 76).color)) } drawLetterVertex(start) diff --git a/src/main/resources/assets/rendering/shader/chunk_vertex.glsl b/src/main/resources/assets/rendering/shader/chunk_vertex.glsl index 559c103cd..1066681a6 100644 --- a/src/main/resources/assets/rendering/shader/chunk_vertex.glsl +++ b/src/main/resources/assets/rendering/shader/chunk_vertex.glsl @@ -8,9 +8,8 @@ out vec3 passTextureCoordinates; uniform mat4 viewMatrix; uniform mat4 projectionMatrix; -uniform vec3 worldPosition; void main() { - gl_Position = projectionMatrix * viewMatrix * vec4(inPosition + vec3(worldPosition.x * 16u, worldPosition.y * 16u, worldPosition.z * 16u), 1.0f); + gl_Position = projectionMatrix * viewMatrix * vec4(inPosition, 1.0f); passTextureCoordinates = vec3(textureIndex, textureLayer); } diff --git a/src/main/resources/assets/rendering/shader/font_vertex.glsl b/src/main/resources/assets/rendering/shader/font_vertex.glsl index 5243cc2a3..964654933 100644 --- a/src/main/resources/assets/rendering/shader/font_vertex.glsl +++ b/src/main/resources/assets/rendering/shader/font_vertex.glsl @@ -1,8 +1,8 @@ #version 330 core layout (location = 0) in vec3 inPosition; layout (location = 1) in vec2 textureIndex; -layout (location = 2) in float textureLayer; -layout (location = 3) in vec4 charColor; +layout (location = 2) in uint textureLayer; +layout (location = 3) in uint charColor; out vec3 passTextureCoordinates; @@ -11,5 +11,6 @@ out vec4 passCharColor; void main() { gl_Position = vec4(inPosition.xyz, 1.0f); passTextureCoordinates = vec3(textureIndex, textureLayer); - passCharColor = charColor; + // uncompact array: 8 bit each for red, gree, blue, alpha + passCharColor = vec4(((charColor >> 24u) & 0xFFu) / 255.0f, ((charColor >> 16u) & 0xFFu) / 255.0f, ((charColor >> 8u) & 0xFFu) / 255.0f, (charColor & 0xFFu) / 255.0f); }