mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 10:55:01 -04:00
rendering: improve multi texture using
This commit is contained in:
parent
85e0c5a95a
commit
c7c3f59a9b
@ -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) {
|
||||||
|
@ -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) {}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user