rendering: improve multi texture using

This commit is contained in:
Bixilon 2021-02-18 22:42:37 +01:00
parent 85e0c5a95a
commit c7c3f59a9b
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
11 changed files with 78 additions and 30 deletions

View File

@ -217,9 +217,11 @@ class RenderWindow(private val connection: Connection, val rendering: Rendering)
chunkRenderer.init() chunkRenderer.init()
hudRenderer.init() hudRenderer.init()
chunkRenderer.postInit()
hudRenderer.postInit()
glfwSetWindowSizeCallback(windowId, object : GLFWWindowSizeCallback() { glfwSetWindowSizeCallback(windowId, object : GLFWWindowSizeCallback() {
override fun invoke(window: Long, width: Int, height: Int) { override fun invoke(window: Long, width: Int, height: Int) {

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering
interface Renderer { interface Renderer {
fun init() fun init()
fun postInit()
fun draw() fun draw()
fun screenChangeResizeCallback(width: Int, height: Int) {} fun screenChangeResizeCallback(width: Int, height: Int) {}
} }

View File

@ -19,20 +19,23 @@ import de.bixilon.minosoft.data.world.*
import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.shader.Shader import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.shader.ShaderTextureBuffer
import de.bixilon.minosoft.gui.rendering.textures.Texture import de.bixilon.minosoft.gui.rendering.textures.Texture
import de.bixilon.minosoft.gui.rendering.textures.TextureArray import de.bixilon.minosoft.gui.rendering.textures.TextureArray
import de.bixilon.minosoft.protocol.network.Connection import de.bixilon.minosoft.protocol.network.Connection
import de.bixilon.minosoft.protocol.protocol.OutByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import glm_.vec3.Vec3 import glm_.vec3.Vec3
import org.lwjgl.opengl.GL11.GL_CULL_FACE import org.lwjgl.opengl.GL11.GL_CULL_FACE
import org.lwjgl.opengl.GL11.glEnable import org.lwjgl.opengl.GL11.glEnable
import org.lwjgl.opengl.GL13.GL_TEXTURE0
import org.lwjgl.opengl.GL13.glDisable import org.lwjgl.opengl.GL13.glDisable
import java.nio.ByteBuffer
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
class ChunkRenderer(private val connection: Connection, private val world: World, val renderWindow: RenderWindow) : Renderer { class ChunkRenderer(private val connection: Connection, private val world: World, val renderWindow: RenderWindow) : Renderer {
private lateinit var minecraftTextures: TextureArray private lateinit var minecraftTextures: TextureArray
lateinit var chunkShader: Shader lateinit var chunkShader: Shader
lateinit var chunkShaderDataBuffer: ShaderTextureBuffer
private val chunkSectionsToDraw = ConcurrentHashMap<ChunkLocation, ConcurrentHashMap<Int, WorldMesh>>() private val chunkSectionsToDraw = ConcurrentHashMap<ChunkLocation, ConcurrentHashMap<Int, WorldMesh>>()
private var currentTick = 0 // for animation usage private var currentTick = 0 // for animation usage
private var lastTickIncrementTime = 0L private var lastTickIncrementTime = 0L
@ -98,28 +101,31 @@ class ChunkRenderer(private val connection: Connection, private val world: World
minecraftTextures = TextureArray.createTextureArray(connection.version.assetsManager, resolveBlockTextureIds(connection.version.mapping.blockIdMap.values)) minecraftTextures = TextureArray.createTextureArray(connection.version.assetsManager, resolveBlockTextureIds(connection.version.mapping.blockIdMap.values))
minecraftTextures.load() minecraftTextures.load()
chunkShaderDataBuffer = ShaderTextureBuffer()
for (texture in minecraftTextures.textures) {
val buffer = ByteBuffer.allocate(12)
val byteBuffer = OutByteBuffer()
byteBuffer.writeInt(texture.animationFrameTime)
byteBuffer.writeInt(texture.animations)
byteBuffer.writeFloat(texture.heightFactor)
byteBuffer.writeTo(buffer)
chunkShaderDataBuffer.data[texture.id] = buffer
}
// chunkShaderDataBuffer.load()
chunkShader = Shader("chunk_vertex.glsl", "chunk_fragment.glsl") chunkShader = Shader("chunk_vertex.glsl", "chunk_fragment.glsl")
// ToDo: chunkShader.replace("%{textureSize}", minecraftTextures.textures.size) // ToDo: chunkShader.replace("%{textureSize}", minecraftTextures.textures.size)
chunkShader.load() chunkShader.load()
chunkShader.use()
chunkShader.setInt("textureCount", minecraftTextures.textures.size)
val animatedTextureFrameTimes: MutableList<Int> = mutableListOf()
val animatedTextureAnimations: MutableList<Int> = mutableListOf()
val textureSingleSizeY: MutableList<Float> = mutableListOf()
for (texture in minecraftTextures.textures) { }
animatedTextureFrameTimes.add(texture.animationFrameTime)
animatedTextureAnimations.add(texture.animations) override fun postInit() {
textureSingleSizeY.add(texture.heightFactor) minecraftTextures.use(chunkShader, "blockTextureArray")
}
chunkShader.setArray("animatedTextureFrameTimes", animatedTextureFrameTimes.toTypedArray())
chunkShader.setArray("animatedTextureAnimations", animatedTextureAnimations.toTypedArray())
chunkShader.setArray("textureSingleSizeY", textureSingleSizeY.toTypedArray())
} }
override fun draw() { override fun draw() {
glEnable(GL_CULL_FACE) glEnable(GL_CULL_FACE)
minecraftTextures.use(GL_TEXTURE0)
chunkShader.use() chunkShader.use()
val currentTime = System.currentTimeMillis() val currentTime = System.currentTimeMillis()

View File

@ -35,6 +35,12 @@ class HUDRenderer(private val connection: Connection, renderWindow: RenderWindow
} }
} }
override fun postInit() {
for (element in hudElements.values) {
element.postInit()
}
}
override fun screenChangeResizeCallback(width: Int, height: Int) { override fun screenChangeResizeCallback(width: Int, height: Int) {
for (element in hudElements.values) { for (element in hudElements.values) {
element.screenChangeResizeCallback(width, height) element.screenChangeResizeCallback(width, height)

View File

@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.hud.elements
interface HUDElement { interface HUDElement {
fun init() fun init()
fun postInit()
fun prepare() fun prepare()
fun update() fun update()
fun draw() fun draw()

View File

@ -28,7 +28,6 @@ import glm_.glm
import glm_.mat4x4.Mat4 import glm_.mat4x4.Mat4
import glm_.vec2.Vec2 import glm_.vec2.Vec2
import glm_.vec4.Vec4 import glm_.vec4.Vec4
import org.lwjgl.opengl.GL13.GL_TEXTURE0
class HUDTextElement(val connection: Connection, val hudRenderer: HUDRenderer, val renderWindow: RenderWindow) : HUDElement { class HUDTextElement(val connection: Connection, val hudRenderer: HUDRenderer, val renderWindow: RenderWindow) : HUDElement {
private val fontBindingPerspectiveMatrices = mutableListOf(Mat4(), Mat4(), Mat4(), Mat4()) // according to FontBindings::ordinal private val fontBindingPerspectiveMatrices = mutableListOf(Mat4(), Mat4(), Mat4(), Mat4()) // according to FontBindings::ordinal
@ -125,23 +124,32 @@ class HUDTextElement(val connection: Connection, val hudRenderer: HUDRenderer, v
hudMeshHUD = HUDFontMesh(meshData.toFloatArray()) hudMeshHUD = HUDFontMesh(meshData.toFloatArray())
} }
override fun init() { override fun init() {
font.load(connection.version.assetsManager) font.load(connection.version.assetsManager)
fontShader = Shader("font_vertex.glsl", "font_fragment.glsl")
fontShader.load()
hudMeshHUD = HUDFontMesh(floatArrayOf())
fontAtlasTexture = font.createAtlasTexture() fontAtlasTexture = font.createAtlasTexture()
fontAtlasTexture.load() fontAtlasTexture.load()
hudMeshHUD = HUDFontMesh(floatArrayOf())
fontShader = Shader("font_vertex.glsl", "font_fragment.glsl")
fontShader.load()
// fontAtlasTexture.use(fontShader, "textureArray")
for (hudTextElement in hudTextElements.values) { for (hudTextElement in hudTextElements.values) {
hudTextElement.init() hudTextElement.init()
} }
} }
override fun postInit() {
fontAtlasTexture.use(fontShader, "fontTextureArray")
}
override fun draw() { override fun draw() {
fontAtlasTexture.use(GL_TEXTURE0)
fontShader.use() fontShader.use()
for (hudTextElement in hudTextElements.values) { for (hudTextElement in hudTextElements.values) {

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.shader package de.bixilon.minosoft.gui.rendering.shader
import de.bixilon.minosoft.gui.rendering.exceptions.ShaderLoadingException import de.bixilon.minosoft.gui.rendering.exceptions.ShaderLoadingException
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
import de.bixilon.minosoft.gui.rendering.util.OpenGLUtil import de.bixilon.minosoft.gui.rendering.util.OpenGLUtil
import glm_.mat4x4.Mat4 import glm_.mat4x4.Mat4
import glm_.vec2.Vec2 import glm_.vec2.Vec2
@ -65,8 +66,8 @@ class Shader(private val vertexPath: String, private val fragmentPath: String) {
return this return this
} }
private fun getUniformLocation(variableName: String): Int { fun getUniformLocation(uniformName: String): Int {
return glGetUniformLocation(programId, variableName) return glGetUniformLocation(programId, uniformName)
} }
fun setFloat(uniformName: String, value: Float) { fun setFloat(uniformName: String, value: Float) {
@ -104,6 +105,10 @@ class Shader(private val vertexPath: String, private val fragmentPath: String) {
} }
} }
fun setTexture(uniformName: String, textureArray: TextureArray) {
glUniform1i(getUniformLocation(uniformName), textureArray.textureId)
}
companion object { companion object {
private var usedShader: Shader? = null private var usedShader: Shader? = null

View File

@ -14,10 +14,10 @@
package de.bixilon.minosoft.gui.rendering.textures package de.bixilon.minosoft.gui.rendering.textures
import de.bixilon.minosoft.data.assets.AssetsManager import de.bixilon.minosoft.data.assets.AssetsManager
import org.lwjgl.opengl.GL11.* import de.bixilon.minosoft.gui.rendering.shader.Shader
import org.lwjgl.opengl.GL12.glTexImage3D import org.lwjgl.opengl.GL12.glTexImage3D
import org.lwjgl.opengl.GL12.glTexSubImage3D import org.lwjgl.opengl.GL12.glTexSubImage3D
import org.lwjgl.opengl.GL13.glActiveTexture import org.lwjgl.opengl.GL13.*
import org.lwjgl.opengl.GL30.GL_TEXTURE_2D_ARRAY import org.lwjgl.opengl.GL30.GL_TEXTURE_2D_ARRAY
import org.lwjgl.opengl.GL30.glGenerateMipmap import org.lwjgl.opengl.GL30.glGenerateMipmap
import java.nio.ByteBuffer import java.nio.ByteBuffer
@ -50,6 +50,12 @@ class TextureArray(val textures: List<Texture>, val maxWidth: Int, val maxHeight
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId) glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
} }
fun use(shader: Shader, arrayName: String) {
glActiveTexture(GL_TEXTURE0 + textureId)
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
shader.use().setTexture(arrayName, this)
}
companion object { companion object {
val DEBUG_TEXTURE = Texture("block/debug", 0) val DEBUG_TEXTURE = Texture("block/debug", 0)

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.util.Util; import de.bixilon.minosoft.util.Util;
import de.bixilon.minosoft.util.nbt.tag.CompoundTag; import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.UUID; import java.util.UUID;
@ -32,6 +33,12 @@ public class OutByteBuffer {
private final Connection connection; private final Connection connection;
private final int versionId; private final int versionId;
public OutByteBuffer() {
this.bytes = new ArrayList<>();
this.connection = null;
this.versionId = -1;
}
public OutByteBuffer(Connection connection) { public OutByteBuffer(Connection connection) {
this.bytes = new ArrayList<>(); this.bytes = new ArrayList<>();
this.connection = connection; this.connection = connection;
@ -248,4 +255,10 @@ public class OutByteBuffer {
public Connection getConnection() { public Connection getConnection() {
return this.connection; return this.connection;
} }
public void writeTo(ByteBuffer buffer) {
for (byte b : this.bytes) {
buffer.put(b);
}
}
} }

View File

@ -17,10 +17,10 @@ out vec4 outColor;
in vec3 passTextureCoordinates; in vec3 passTextureCoordinates;
uniform sampler2DArray texureArray; uniform sampler2DArray blockTextureArray;
void main() { void main() {
vec4 texColor = texture(texureArray, passTextureCoordinates); vec4 texColor = texture(blockTextureArray, passTextureCoordinates);
if (texColor.a == 0) { // ToDo: This only works for alpha == 0. What about semi transparency? We would need to sort the faces, etc. See: https://learnopengl.com/Advanced-OpenGL/Blending if (texColor.a == 0) { // ToDo: This only works for alpha == 0. What about semi transparency? We would need to sort the faces, etc. See: https://learnopengl.com/Advanced-OpenGL/Blending
discard; discard;
} }

View File

@ -18,11 +18,11 @@ out vec4 outColor;
in vec3 passTextureCoordinates; in vec3 passTextureCoordinates;
in vec4 passCharColor; in vec4 passCharColor;
uniform sampler2DArray texureArray; uniform sampler2DArray fontTextureArray;
void main() { void main() {
vec4 textureColor = texture(texureArray, passTextureCoordinates); vec4 textureColor = texture(fontTextureArray, passTextureCoordinates);
if (passCharColor.a == 1.0f && textureColor.a == 0) { if (passCharColor.a == 1.0f && textureColor.a == 0) {
discard; discard;
} }