mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 11:54:59 -04:00
wip lightmap
This commit is contained in:
parent
96e80b909c
commit
30e0a1a8a0
@ -30,6 +30,9 @@ class WorldLightAccessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getBlockLight(blockPosition: Vec3i): Int {
|
override fun getBlockLight(blockPosition: Vec3i): Int {
|
||||||
|
if (RenderConstants.DISABLE_LIGHTING) {
|
||||||
|
return 15
|
||||||
|
}
|
||||||
return world.chunks[blockPosition.chunkPosition]?.lightAccessor?.getBlockLight(blockPosition) ?: 0
|
return world.chunks[blockPosition.chunkPosition]?.lightAccessor?.getBlockLight(blockPosition) ?: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ object RenderConstants {
|
|||||||
|
|
||||||
const val MAXIMUM_QUEUE_TIME_PER_FRAME = 100L
|
const val MAXIMUM_QUEUE_TIME_PER_FRAME = 100L
|
||||||
|
|
||||||
const val DISABLE_LIGHTING = true
|
const val DISABLE_LIGHTING = false
|
||||||
|
|
||||||
const val RENDER_BLOCKS = true
|
const val RENDER_BLOCKS = true
|
||||||
const val RENDER_FLUIDS = true
|
const val RENDER_FLUIDS = true
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2021 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.block
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.text.RGBColor.Companion.asGray
|
||||||
|
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||||
|
import de.bixilon.minosoft.gui.rendering.system.opengl.FloatUniformBuffer
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
|
|
||||||
|
|
||||||
|
class LightMap(private val connection: PlayConnection) {
|
||||||
|
private val uniformBuffer = FloatUniformBuffer(1, FloatArray(16 * 16 * 4) { 1.0f })
|
||||||
|
private var lastUpdate = -1L
|
||||||
|
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
uniformBuffer.init()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun use(shader: Shader, bufferName: String = "uLightMapBuffer") {
|
||||||
|
uniformBuffer.use(shader, bufferName)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update() {
|
||||||
|
val currentTime = System.currentTimeMillis()
|
||||||
|
if (currentTime - lastUpdate < ProtocolDefinition.TICK_TIME * 10) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastUpdate = currentTime
|
||||||
|
|
||||||
|
// ToDo
|
||||||
|
for (skyLight in 0 until 16) {
|
||||||
|
for (blockLight in 0 until 16) {
|
||||||
|
val index = ((skyLight shl 4) or blockLight) * 4
|
||||||
|
|
||||||
|
val color = ((blockLight + skyLight) / 30.0f).asGray()
|
||||||
|
|
||||||
|
uniformBuffer.data[index + 0] = color.floatRed
|
||||||
|
uniformBuffer.data[index + 1] = color.floatRed
|
||||||
|
uniformBuffer.data[index + 2] = color.floatGreen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uniformBuffer.upload()
|
||||||
|
}
|
||||||
|
}
|
@ -63,6 +63,7 @@ class WorldRenderer(
|
|||||||
private val waterBlock = connection.registries.blockRegistry[ResourceLocation("minecraft:water")]?.nullCast<FluidBlock>()
|
private val waterBlock = connection.registries.blockRegistry[ResourceLocation("minecraft:water")]?.nullCast<FluidBlock>()
|
||||||
|
|
||||||
lateinit var chunkShader: Shader
|
lateinit var chunkShader: Shader
|
||||||
|
private val lightMap = LightMap(connection)
|
||||||
|
|
||||||
val allChunkSections: SynchronizedMap<Vec2i, SynchronizedMap<Int, ChunkSectionMeshCollection>> = synchronizedMapOf()
|
val allChunkSections: SynchronizedMap<Vec2i, SynchronizedMap<Int, ChunkSectionMeshCollection>> = synchronizedMapOf()
|
||||||
val visibleChunks: SynchronizedMap<Vec2i, SynchronizedMap<Int, ChunkSectionMeshCollection>> = synchronizedMapOf()
|
val visibleChunks: SynchronizedMap<Vec2i, SynchronizedMap<Int, ChunkSectionMeshCollection>> = synchronizedMapOf()
|
||||||
@ -182,12 +183,14 @@ class WorldRenderer(
|
|||||||
check(renderWindow.textures.animator.animatedTextures.size < TextureArray.MAX_ANIMATED_TEXTURES) { "Can not have more than ${TextureArray.MAX_ANIMATED_TEXTURES} animated textures!" }
|
check(renderWindow.textures.animator.animatedTextures.size < TextureArray.MAX_ANIMATED_TEXTURES) { "Can not have more than ${TextureArray.MAX_ANIMATED_TEXTURES} animated textures!" }
|
||||||
chunkShader = Shader(
|
chunkShader = Shader(
|
||||||
renderWindow = renderWindow,
|
renderWindow = renderWindow,
|
||||||
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "chunk"),
|
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world"),
|
||||||
)
|
)
|
||||||
chunkShader.load()
|
chunkShader.load()
|
||||||
|
lightMap.init()
|
||||||
|
|
||||||
renderWindow.textures.use(chunkShader)
|
renderWindow.textures.use(chunkShader)
|
||||||
renderWindow.textures.animator.use(chunkShader, "uAnimationBuffer")
|
renderWindow.textures.animator.use(chunkShader)
|
||||||
|
lightMap.use(chunkShader)
|
||||||
|
|
||||||
for (blockState in allBlocks!!) {
|
for (blockState in allBlocks!!) {
|
||||||
for (model in blockState.renderers) {
|
for (model in blockState.renderers) {
|
||||||
@ -199,6 +202,7 @@ class WorldRenderer(
|
|||||||
|
|
||||||
override fun update() {
|
override fun update() {
|
||||||
lastVisibleChunks = visibleChunks.toSynchronizedMap()
|
lastVisibleChunks = visibleChunks.toSynchronizedMap()
|
||||||
|
lightMap.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun draw() {
|
override fun draw() {
|
||||||
|
@ -24,13 +24,9 @@ import glm_.vec3.Vec3
|
|||||||
|
|
||||||
class ChunkSectionArrayMesh : Mesh(SectionArrayMeshStruct::class, initialCacheSize = 100000) {
|
class ChunkSectionArrayMesh : Mesh(SectionArrayMeshStruct::class, initialCacheSize = 100000) {
|
||||||
|
|
||||||
fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Int = 14) {
|
fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, light: Int) {
|
||||||
val color = tintColor ?: ChatColors.WHITE
|
val color = tintColor ?: ChatColors.WHITE
|
||||||
|
|
||||||
val lightFactor = (lightLevel + 1) / MAX_LIGHT_LEVEL_FLOAT
|
|
||||||
|
|
||||||
val lightColor = RGBColor((color.red * lightFactor).toInt(), (color.green * lightFactor).toInt(), (color.blue * lightFactor).toInt())
|
|
||||||
|
|
||||||
val textureLayer = if (RenderConstants.FORCE_DEBUG_TEXTURE) {
|
val textureLayer = if (RenderConstants.FORCE_DEBUG_TEXTURE) {
|
||||||
RenderConstants.DEBUG_TEXTURE_ID
|
RenderConstants.DEBUG_TEXTURE_ID
|
||||||
} else {
|
} else {
|
||||||
@ -44,7 +40,8 @@ class ChunkSectionArrayMesh : Mesh(SectionArrayMeshStruct::class, initialCacheSi
|
|||||||
textureCoordinates.y * texture.uvEnd.y,
|
textureCoordinates.y * texture.uvEnd.y,
|
||||||
Float.fromBits(textureLayer),
|
Float.fromBits(textureLayer),
|
||||||
Float.fromBits(texture.properties.animation?.animationId ?: -1),
|
Float.fromBits(texture.properties.animation?.animationId ?: -1),
|
||||||
Float.fromBits(lightColor.rgb),
|
Float.fromBits(color.rgb),
|
||||||
|
Float.fromBits(light)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +58,7 @@ class ChunkSectionArrayMesh : Mesh(SectionArrayMeshStruct::class, initialCacheSi
|
|||||||
val textureLayer: Int,
|
val textureLayer: Int,
|
||||||
val animationId: Int,
|
val animationId: Int,
|
||||||
val tintColor: RGBColor,
|
val tintColor: RGBColor,
|
||||||
|
val light: Int,
|
||||||
) {
|
) {
|
||||||
companion object : MeshStruct(SectionArrayMeshStruct::class)
|
companion object : MeshStruct(SectionArrayMeshStruct::class)
|
||||||
}
|
}
|
||||||
|
@ -94,8 +94,11 @@ class ElementRenderer(
|
|||||||
|
|
||||||
finalColor = finalColor.with(finalColor.floatRed * shadeLevel, finalColor.floatGreen * shadeLevel, finalColor.floatBlue * shadeLevel)
|
finalColor = finalColor.with(finalColor.floatRed * shadeLevel, finalColor.floatGreen * shadeLevel, finalColor.floatBlue * shadeLevel)
|
||||||
|
|
||||||
val lightLevel = context.lightAccessor.getLightLevel(context.blockPosition + face.cullFace?.let { directionMapping[it] }) // ToDo: rotate cullface
|
val lightPosition = context.blockPosition + face.cullFace?.let { directionMapping[it] }// ToDo: rotate cullface
|
||||||
|
val blockLight = context.lightAccessor.getBlockLight(lightPosition)
|
||||||
|
val skyLight = context.lightAccessor.getSkyLight(lightPosition)
|
||||||
|
|
||||||
|
val light = (skyLight shl 4) or blockLight
|
||||||
val drawPositions = mutableListOf<Vec3>()
|
val drawPositions = mutableListOf<Vec3>()
|
||||||
for (position in positionTemplate) {
|
for (position in positionTemplate) {
|
||||||
drawPositions += transformedPositions[position]
|
drawPositions += transformedPositions[position]
|
||||||
@ -113,7 +116,7 @@ class ElementRenderer(
|
|||||||
textureCoordinates = texturePositions[texturePositionIndex]!!,
|
textureCoordinates = texturePositions[texturePositionIndex]!!,
|
||||||
texture = texture,
|
texture = texture,
|
||||||
tintColor = finalColor,
|
tintColor = finalColor,
|
||||||
lightLevel = lightLevel,
|
light = light,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ class FluidRenderer(
|
|||||||
textureCoordinates = texturePositions[vertex.second]!!,
|
textureCoordinates = texturePositions[vertex.second]!!,
|
||||||
texture = texture,
|
texture = texture,
|
||||||
tintColor = tintColor,
|
tintColor = tintColor,
|
||||||
lightLevel = lightLevel,
|
light = lightLevel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Minosoft
|
||||||
|
* Copyright (C) 2021 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.system.opengl
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.ARBUniformBufferObject.GL_UNIFORM_BUFFER
|
||||||
|
import org.lwjgl.opengl.GL15.*
|
||||||
|
|
||||||
|
class FloatUniformBuffer(bindingIndex: Int = 0, var data: FloatArray = FloatArray(0)) : UniformBuffer(bindingIndex) {
|
||||||
|
override val size: Int
|
||||||
|
get() = data.size
|
||||||
|
|
||||||
|
override fun initialUpload() {
|
||||||
|
bind()
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, data, GL_DYNAMIC_DRAW)
|
||||||
|
unbind()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun upload() {
|
||||||
|
check(initialSize == size) { "Can not change buffer size!" }
|
||||||
|
bind()
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, data)
|
||||||
|
unbind()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.system.opengl
|
|||||||
import org.lwjgl.opengl.ARBUniformBufferObject.GL_UNIFORM_BUFFER
|
import org.lwjgl.opengl.ARBUniformBufferObject.GL_UNIFORM_BUFFER
|
||||||
import org.lwjgl.opengl.GL15.*
|
import org.lwjgl.opengl.GL15.*
|
||||||
|
|
||||||
class IntUniformBuffer(var data: IntArray = IntArray(0)) : UniformBuffer() {
|
class IntUniformBuffer(bindingIndex: Int = 0, var data: IntArray = IntArray(0)) : UniformBuffer(bindingIndex) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = data.size
|
get() = data.size
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import org.lwjgl.opengl.ARBUniformBufferObject.*
|
|||||||
import org.lwjgl.opengl.GL15.glBindBuffer
|
import org.lwjgl.opengl.GL15.glBindBuffer
|
||||||
import org.lwjgl.opengl.GL15.glGenBuffers
|
import org.lwjgl.opengl.GL15.glGenBuffers
|
||||||
|
|
||||||
abstract class UniformBuffer {
|
abstract class UniformBuffer(private val bindingIndex: Int) {
|
||||||
private var id = -1
|
private var id = -1
|
||||||
protected abstract val size: Int
|
protected abstract val size: Int
|
||||||
protected var initialSize = -1
|
protected var initialSize = -1
|
||||||
@ -27,7 +27,7 @@ abstract class UniformBuffer {
|
|||||||
fun init() {
|
fun init() {
|
||||||
id = glGenBuffers()
|
id = glGenBuffers()
|
||||||
initialUpload()
|
initialUpload()
|
||||||
glBindBufferRange(GL_UNIFORM_BUFFER, 0, id, 0, size.toLong())
|
glBindBufferRange(GL_UNIFORM_BUFFER, bindingIndex, id, 0, size.toLong())
|
||||||
initialSize = size
|
initialSize = size
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,8 +43,8 @@ abstract class UniformBuffer {
|
|||||||
fun use(shader: Shader, bufferName: String) {
|
fun use(shader: Shader, bufferName: String) {
|
||||||
shader.use()
|
shader.use()
|
||||||
|
|
||||||
shader.setUniformBuffer(bufferName, 0)
|
shader.setUniformBuffer(bufferName, bindingIndex)
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, id)
|
glBindBufferBase(GL_UNIFORM_BUFFER, bindingIndex, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun initialUpload()
|
protected abstract fun initialUpload()
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
layout(std140) uniform uLightMapBuffer
|
||||||
|
{
|
||||||
|
vec4 uLightMap[16 * 16];// ToDo: uint[256] should work without padding, but it seems there is padding. Using vec4 for now.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
vec4 getLight(uint light) {
|
||||||
|
return uLightMap[light];
|
||||||
|
}
|
@ -19,6 +19,7 @@ layout (location = 2) in uint vinTextureLayer;
|
|||||||
|
|
||||||
layout (location = 3) in int vinAnimationIndex;
|
layout (location = 3) in int vinAnimationIndex;
|
||||||
layout (location = 4) in uint vinTintColor;
|
layout (location = 4) in uint vinTintColor;
|
||||||
|
layout (location = 5) in uint vinLight;
|
||||||
|
|
||||||
flat out uint finTextureIndex1;
|
flat out uint finTextureIndex1;
|
||||||
out vec3 finTextureCoordinates1;
|
out vec3 finTextureCoordinates1;
|
||||||
@ -35,9 +36,11 @@ uniform mat4 uViewProjectionMatrix;
|
|||||||
|
|
||||||
#include "minosoft:color"
|
#include "minosoft:color"
|
||||||
|
|
||||||
|
#include "minosoft:light"
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = uViewProjectionMatrix * vec4(vinPosition, 1.0f);
|
gl_Position = uViewProjectionMatrix * vec4(vinPosition, 1.0f);
|
||||||
finTintColor = getRGBColor(vinTintColor);
|
finTintColor = getRGBColor(vinTintColor) * getLight(vinLight);
|
||||||
|
|
||||||
|
|
||||||
if (vinAnimationIndex == -1) {
|
if (vinAnimationIndex == -1) {
|
Loading…
x
Reference in New Issue
Block a user