rendering: workaround max uniform restriction for animated textures

This commit is contained in:
Bixilon 2021-02-19 00:01:31 +01:00
parent c7c3f59a9b
commit f8bf10fb2a
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
6 changed files with 35 additions and 40 deletions

View File

@ -13,29 +13,26 @@
package de.bixilon.minosoft.gui.rendering.chunk
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.mappings.blocks.Block
import de.bixilon.minosoft.data.world.*
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.Renderer
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.TextureArray
import de.bixilon.minosoft.protocol.network.Connection
import de.bixilon.minosoft.protocol.protocol.OutByteBuffer
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import glm_.vec3.Vec3
import org.lwjgl.opengl.GL11.GL_CULL_FACE
import org.lwjgl.opengl.GL11.glEnable
import org.lwjgl.opengl.GL13.glDisable
import java.nio.ByteBuffer
import java.util.concurrent.ConcurrentHashMap
class ChunkRenderer(private val connection: Connection, private val world: World, val renderWindow: RenderWindow) : Renderer {
private lateinit var minecraftTextures: TextureArray
lateinit var chunkShader: Shader
lateinit var chunkShaderDataBuffer: ShaderTextureBuffer
private val chunkSectionsToDraw = ConcurrentHashMap<ChunkLocation, ConcurrentHashMap<Int, WorldMesh>>()
private var currentTick = 0 // for animation usage
private var lastTickIncrementTime = 0L
@ -101,18 +98,6 @@ class ChunkRenderer(private val connection: Connection, private val world: World
minecraftTextures = TextureArray.createTextureArray(connection.version.assetsManager, resolveBlockTextureIds(connection.version.mapping.blockIdMap.values))
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")
// ToDo: chunkShader.replace("%{textureSize}", minecraftTextures.textures.size)
@ -128,11 +113,13 @@ class ChunkRenderer(private val connection: Connection, private val world: World
glEnable(GL_CULL_FACE)
chunkShader.use()
if (Minosoft.getConfig().config.game.animations.textures) {
val currentTime = System.currentTimeMillis()
if (currentTime - lastTickIncrementTime >= ProtocolDefinition.TICK_TIME) {
chunkShader.setInt("currentTick", currentTick++)
chunkShader.setInt("animationTick", currentTick++)
lastTickIncrementTime = currentTime
}
}
for ((_, map) in chunkSectionsToDraw) {
for ((_, mesh) in map) {

View File

@ -29,12 +29,18 @@ class WorldMesh(data: FloatArray) {
glBindVertexArray(vAO)
glBindBuffer(GL_ARRAY_BUFFER, vBO)
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, 0L)
glEnableVertexAttribArray(0)
glVertexAttribPointer(1, 2, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, (3 * Float.BYTES).toLong())
glEnableVertexAttribArray(1)
glVertexAttribPointer(2, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, (5 * Float.BYTES).toLong())
glEnableVertexAttribArray(2)
var index = 0
glVertexAttribPointer(index, 3, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, 0L)
glEnableVertexAttribArray(index++)
glVertexAttribPointer(index, 2, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, (3 * Float.BYTES).toLong())
glEnableVertexAttribArray(index++)
glVertexAttribPointer(index, 1, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, (5 * Float.BYTES).toLong())
glEnableVertexAttribArray(index++)
glVertexAttribPointer(index, 3, GL_FLOAT, false, FLOATS_PER_VERTEX * Float.BYTES, (6 * Float.BYTES).toLong())
glEnableVertexAttribArray(index)
// 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)
@ -51,6 +57,6 @@ class WorldMesh(data: FloatArray) {
}
companion object {
private const val FLOATS_PER_VERTEX = 6
private const val FLOATS_PER_VERTEX = 9
}
}

View File

@ -140,6 +140,11 @@ open class BlockModelElement(data: JsonObject) {
data.add(textureCoordinates.x * texture.widthFactor)
data.add(textureCoordinates.y * texture.heightFactor)
data.add(Float.fromBits(texture.id)) // ToDo: Compact this
// ToDo: Send this only once per texture
data.add(texture.animationFrameTime.toFloat())
data.add(texture.animations.toFloat())
data.add(texture.heightFactor)
}
fun createQuad(drawPositions: Array<Vec3>, texturePositions: IntArray) {

View File

@ -66,7 +66,7 @@ class Shader(private val vertexPath: String, private val fragmentPath: String) {
return this
}
fun getUniformLocation(uniformName: String): Int {
private fun getUniformLocation(uniformName: String): Int {
return glGetUniformLocation(programId, uniformName)
}
@ -106,7 +106,7 @@ class Shader(private val vertexPath: String, private val fragmentPath: String) {
}
fun setTexture(uniformName: String, textureArray: TextureArray) {
glUniform1i(getUniformLocation(uniformName), textureArray.textureId)
glUniform1i(getUniformLocation(uniformName), textureArray.textureId - 1)
}

View File

@ -51,7 +51,7 @@ class TextureArray(val textures: List<Texture>, val maxWidth: Int, val maxHeight
}
fun use(shader: Shader, arrayName: String) {
glActiveTexture(GL_TEXTURE0 + textureId)
glActiveTexture(GL_TEXTURE0 + textureId - 1)
glBindTexture(GL_TEXTURE_2D_ARRAY, textureId)
shader.use().setTexture(arrayName, this)
}

View File

@ -17,25 +17,22 @@ layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 textureIndex;
layout (location = 2) in int textureLayer;
layout (location = 3) in vec3 animatedTextureData;
out vec3 passTextureCoordinates;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform int currentTick;
uniform int animationTick;
const int TEXTURE_COUNT = 1024;
uniform int[TEXTURE_COUNT] animatedTextureFrameTimes;// ToDo: Support frames more textures
uniform int[TEXTURE_COUNT] animatedTextureAnimations;
uniform float[TEXTURE_COUNT] textureSingleSizeY;
void main() {
gl_Position = projectionMatrix * viewMatrix * vec4(inPosition, 1.0f);
int textureAnimations = animatedTextureAnimations[textureLayer];
if (textureAnimations == 1) {
if (animatedTextureData.y == 1.0f) {
passTextureCoordinates = vec3(textureIndex, textureLayer);
return;
}
int frameTime = animatedTextureFrameTimes[textureLayer];
passTextureCoordinates = vec3(textureIndex.x, textureIndex.y + (textureSingleSizeY[textureLayer] * ((currentTick / frameTime) % textureAnimations)), textureLayer);
// passTextureCoordinates = vec3(0,0,0);
passTextureCoordinates = vec3(textureIndex.x, textureIndex.y + (animatedTextureData.z * ((animationTick / int(animatedTextureData.x)) % int(animatedTextureData.y))), textureLayer);
}