mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-14 09:56:37 -04:00
wip improve shaders, replace all rendering callbacks with events
This commit is contained in:
parent
250778e608
commit
2fdad3dbce
@ -20,13 +20,14 @@ import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
|
||||
import de.bixilon.minosoft.data.mappings.biomes.Biome
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.blockPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkSectionPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||
import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.packets.c2s.play.PositionAndRotationC2SP
|
||||
import de.bixilon.minosoft.protocol.packets.c2s.play.PositionC2SP
|
||||
@ -46,7 +47,7 @@ class Camera(
|
||||
val connection: PlayConnection,
|
||||
var fov: Float,
|
||||
val renderWindow: RenderWindow,
|
||||
) : ScreenResizeCallback {
|
||||
) {
|
||||
private var mouseSensitivity = Minosoft.getConfig().config.game.camera.moseSensitivity
|
||||
private val walkingSpeed get() = connection.player.baseAbilities.walkingSpeed * ProtocolDefinition.TICKS_PER_SECOND * 2
|
||||
private val flyingSpeed get() = connection.player.baseAbilities.flyingSpeed * ProtocolDefinition.TICKS_PER_SECOND * 2
|
||||
@ -80,9 +81,6 @@ class Camera(
|
||||
|
||||
val frustum: Frustum = Frustum(this)
|
||||
|
||||
private val shaders: MutableSet<Shader> = mutableSetOf()
|
||||
private val frustumChangeCallbacks: MutableSet<FrustumChangeCallback> = mutableSetOf()
|
||||
|
||||
|
||||
var viewMatrix = calculateViewMatrix()
|
||||
private set
|
||||
@ -135,10 +133,9 @@ class Camera(
|
||||
KeyBindingsNames.MOVE_JUMP,
|
||||
)
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<ScreenResizeEvent> { recalculateViewProjectionMatrix() })
|
||||
frustum.recalculate()
|
||||
for (frustumChangeCallback in frustumChangeCallbacks) {
|
||||
frustumChangeCallback.onFrustumChange()
|
||||
}
|
||||
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
||||
}
|
||||
|
||||
fun handleInput(deltaTime: Double) {
|
||||
@ -211,25 +208,15 @@ class Camera(
|
||||
}
|
||||
}
|
||||
|
||||
fun addShaders(vararg shaders: Shader) {
|
||||
this.shaders.addAll(shaders)
|
||||
}
|
||||
|
||||
fun addFrustumChangeCallback(vararg shaders: FrustumChangeCallback) {
|
||||
this.frustumChangeCallbacks.addAll(shaders)
|
||||
}
|
||||
|
||||
override fun onScreenResize(screenDimensions: Vec2i) {
|
||||
recalculateViewProjectionMatrix()
|
||||
}
|
||||
|
||||
private fun recalculateViewProjectionMatrix() {
|
||||
viewMatrix = calculateViewMatrix()
|
||||
projectionMatrix = calculateProjectionMatrix(renderWindow.screenDimensionsF)
|
||||
viewProjectionMatrix = projectionMatrix * viewMatrix
|
||||
lastMatrixChange = System.currentTimeMillis()
|
||||
for (shader in shaders) {
|
||||
shader.use().setMat4("viewProjectionMatrix", viewProjectionMatrix)
|
||||
for (shader in renderWindow.shaders) {
|
||||
if (shader.uniforms.contains("viewProjectionMatrix")) {
|
||||
shader.use().setMat4("viewProjectionMatrix", viewProjectionMatrix)
|
||||
}
|
||||
}
|
||||
positionChangeCallback()
|
||||
}
|
||||
@ -244,9 +231,7 @@ class Camera(
|
||||
renderWindow.setSkyColor(connection.world.getBiome(blockPosition)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR)
|
||||
|
||||
frustum.recalculate()
|
||||
for (frustumChangeCallback in frustumChangeCallbacks) {
|
||||
frustumChangeCallback.onFrustumChange()
|
||||
}
|
||||
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
||||
|
||||
connection.world.dimension?.hasSkyLight?.let {
|
||||
if (it) {
|
||||
|
@ -18,20 +18,19 @@ import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.data.text.RGBColor.Companion.asColor
|
||||
import de.bixilon.minosoft.gui.input.camera.FrustumChangeCallback
|
||||
import de.bixilon.minosoft.gui.input.key.RenderWindowInputHandler
|
||||
import de.bixilon.minosoft.gui.modding.events.RenderingStateChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.WorldRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.font.Font
|
||||
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLike
|
||||
import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLikeTexture
|
||||
import de.bixilon.minosoft.gui.rendering.shader.ShaderHolder
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
||||
import de.bixilon.minosoft.gui.rendering.util.ScreenshotTaker
|
||||
import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.modding.event.events.ConnectionStateChangeEvent
|
||||
import de.bixilon.minosoft.modding.event.events.PacketReceiveEvent
|
||||
@ -41,7 +40,6 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.CountUpAndDownLatch
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedListOf
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedSetOf
|
||||
import de.bixilon.minosoft.util.Stopwatch
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
@ -84,11 +82,12 @@ class RenderWindow(
|
||||
|
||||
val renderQueue: MutableList<Runnable> = synchronizedListOf()
|
||||
|
||||
|
||||
val shaders: MutableList<Shader> = mutableListOf()
|
||||
|
||||
lateinit var WHITE_TEXTURE: TextureLike
|
||||
|
||||
|
||||
val screenResizeCallbacks: MutableSet<ScreenResizeCallback> = synchronizedSetOf(inputHandler.camera)
|
||||
|
||||
var tickCount = 0L
|
||||
var lastTickTimer = System.currentTimeMillis()
|
||||
|
||||
@ -221,9 +220,6 @@ class RenderWindow(
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Post loading renderer (${stopwatch.labTime()})..." }
|
||||
for (renderer in rendererMap.values) {
|
||||
renderer.postInit()
|
||||
if (renderer is ShaderHolder) {
|
||||
inputHandler.camera.addShaders(renderer.shader)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -231,11 +227,10 @@ class RenderWindow(
|
||||
glfwSetWindowSizeCallback(windowId, object : GLFWWindowSizeCallback() {
|
||||
override fun invoke(window: Long, width: Int, height: Int) {
|
||||
glViewport(0, 0, width, height)
|
||||
val previousSize = screenDimensions
|
||||
screenDimensions = Vec2i(width, height)
|
||||
screenDimensionsF = Vec2(screenDimensions)
|
||||
for (callback in screenResizeCallbacks) {
|
||||
callback.onScreenResize(screenDimensions)
|
||||
}
|
||||
connection.fireEvent(ScreenResizeEvent(previousScreenDimensions = previousSize, screenDimensions = screenDimensions))
|
||||
}
|
||||
})
|
||||
|
||||
@ -266,9 +261,7 @@ class RenderWindow(
|
||||
|
||||
registerGlobalKeyCombinations()
|
||||
|
||||
for (callback in screenResizeCallbacks) {
|
||||
callback.onScreenResize(screenDimensions)
|
||||
}
|
||||
connection.fireEvent(ScreenResizeEvent(previousScreenDimensions = Vec2i(0, 0), screenDimensions = screenDimensions))
|
||||
|
||||
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Rendering is fully prepared in ${stopwatch.totalTime()}" }
|
||||
@ -392,12 +385,6 @@ class RenderWindow(
|
||||
fun registerRenderer(renderBuilder: RenderBuilder) {
|
||||
val renderer = renderBuilder.build(connection, this)
|
||||
rendererMap[renderBuilder.RESOURCE_LOCATION] = renderer
|
||||
if (renderer is ScreenResizeCallback) {
|
||||
screenResizeCallbacks.add(renderer)
|
||||
}
|
||||
if (renderer is FrustumChangeCallback) {
|
||||
inputHandler.camera.addFrustumChangeCallback(renderer)
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated(message = "Will be replaced with SkyRenderer")
|
||||
|
@ -14,7 +14,7 @@
|
||||
package de.bixilon.minosoft.gui.rendering
|
||||
|
||||
interface Renderer {
|
||||
fun init()
|
||||
fun postInit()
|
||||
fun draw()
|
||||
fun init() {}
|
||||
fun postInit() {}
|
||||
fun draw() {}
|
||||
}
|
||||
|
@ -29,10 +29,12 @@ class Rendering(private val connection: PlayConnection) {
|
||||
Thread({
|
||||
try {
|
||||
Log.log(LogMessageType.RENDERING_GENERAL, LogLevels.INFO) { "Hello LWJGL ${Version.getVersion()}!" }
|
||||
CONTEXT_MAP[Thread.currentThread()] = renderWindow
|
||||
renderWindow.init(latch)
|
||||
renderWindow.startRenderLoop()
|
||||
renderWindow.exit()
|
||||
} catch (exception: Throwable) {
|
||||
CONTEXT_MAP.remove(Thread.currentThread())
|
||||
exception.printStackTrace()
|
||||
try {
|
||||
renderWindow.exit()
|
||||
@ -45,4 +47,11 @@ class Rendering(private val connection: PlayConnection) {
|
||||
}
|
||||
}, "Rendering").start()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val CONTEXT_MAP: MutableMap<Thread, RenderWindow> = mutableMapOf()
|
||||
|
||||
val currentContext: RenderWindow?
|
||||
get() = CONTEXT_MAP[Thread.currentThread()]
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,6 @@ import org.lwjgl.opengl.GL20.glVertexAttribPointer
|
||||
class SectionArrayMesh : Mesh(initialCacheSize = 100000) {
|
||||
|
||||
fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Int = 14) {
|
||||
val data = data!!
|
||||
|
||||
val color = tintColor ?: ChatColors.WHITE
|
||||
|
||||
val lightFactor = (lightLevel + 1) / MAX_LIGHT_LEVEL_FLOAT
|
||||
|
@ -25,11 +25,11 @@ import de.bixilon.minosoft.data.world.Chunk
|
||||
import de.bixilon.minosoft.data.world.ChunkSection
|
||||
import de.bixilon.minosoft.data.world.ChunkSection.Companion.indexPosition
|
||||
import de.bixilon.minosoft.data.world.World
|
||||
import de.bixilon.minosoft.gui.input.camera.FrustumChangeCallback
|
||||
import de.bixilon.minosoft.gui.modding.events.RenderingStateChangeEvent
|
||||
import de.bixilon.minosoft.gui.input.camera.Frustum
|
||||
import de.bixilon.minosoft.gui.rendering.*
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.shader.ShaderHolder
|
||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.of
|
||||
@ -52,11 +52,11 @@ import org.lwjgl.opengl.GL11.glDepthMask
|
||||
class WorldRenderer(
|
||||
private val connection: PlayConnection,
|
||||
val renderWindow: RenderWindow,
|
||||
) : Renderer, ShaderHolder, FrustumChangeCallback {
|
||||
) : Renderer {
|
||||
private val world: World = connection.world
|
||||
private val waterBlock = connection.mapping.blockRegistry.get(ResourceLocation("minecraft:water"))?.nullCast<FluidBlock>()
|
||||
|
||||
override lateinit var shader: Shader
|
||||
lateinit var chunkShader: Shader
|
||||
val allChunkSections: MutableMap<Vec2i, MutableMap<Int, ChunkMeshCollection>> = synchronizedMapOf()
|
||||
val visibleChunks: MutableMap<Vec2i, MutableMap<Int, ChunkMeshCollection>> = synchronizedMapOf()
|
||||
val queuedChunks: MutableSet<Vec2i> = synchronizedSetOf()
|
||||
@ -160,19 +160,20 @@ class WorldRenderer(
|
||||
clearChunkCache()
|
||||
}
|
||||
})
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<FrustumChangeEvent> { onFrustumChange(it.frustum) })
|
||||
}
|
||||
|
||||
override fun postInit() {
|
||||
check(renderWindow.textures.animator.animatedTextures.size < 4096) { "Can not have more than 4096 animated textures!" } // uniform buffer limit: 16kb. 4 ints per texture
|
||||
shader = Shader(
|
||||
vertexPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/chunk_vertex.glsl"),
|
||||
fragmentPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/chunk_fragment.glsl"),
|
||||
chunkShader = Shader(
|
||||
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "chunk"),
|
||||
defines = mapOf("ANIMATED_TEXTURE_COUNT" to MMath.clamp(renderWindow.textures.animator.animatedTextures.size, 1, Int.MAX_VALUE)),
|
||||
)
|
||||
shader.load()
|
||||
chunkShader.load()
|
||||
|
||||
renderWindow.textures.use(shader, "textureArray")
|
||||
renderWindow.textures.animator.use(shader, "AnimatedDataBuffer")
|
||||
renderWindow.textures.use(chunkShader, "textureArray")
|
||||
renderWindow.textures.animator.use(chunkShader, "AnimatedDataBuffer")
|
||||
|
||||
for (blockState in allBlocks!!) {
|
||||
for (model in blockState.renderers) {
|
||||
@ -183,7 +184,7 @@ class WorldRenderer(
|
||||
}
|
||||
|
||||
override fun draw() {
|
||||
shader.use()
|
||||
chunkShader.use()
|
||||
val visibleChunks = visibleChunks.toSynchronizedMap()
|
||||
|
||||
for ((_, map) in visibleChunks) {
|
||||
@ -398,13 +399,13 @@ class WorldRenderer(
|
||||
prepareWorld(connection.world)
|
||||
}
|
||||
|
||||
override fun onFrustumChange() {
|
||||
private fun onFrustumChange(frustum: Frustum) {
|
||||
visibleChunks.clear()
|
||||
for ((chunkLocation, rawIndexMap) in allChunkSections.toSynchronizedMap()) {
|
||||
val visibleIndexMap: MutableMap<Int, ChunkMeshCollection> = synchronizedMapOf()
|
||||
val indexMap = rawIndexMap.toMap()
|
||||
for ((index, mesh) in indexMap) {
|
||||
if (renderWindow.inputHandler.camera.frustum.containsChunk(chunkLocation, mesh.lowestBlockHeight, mesh.highestBlockHeight)) {
|
||||
if (frustum.containsChunk(chunkLocation, mesh.lowestBlockHeight, mesh.highestBlockHeight)) {
|
||||
visibleIndexMap[index] = mesh
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class HUDMesh : Mesh() {
|
||||
}
|
||||
|
||||
fun addCacheMesh(cacheMesh: HUDCacheMesh) {
|
||||
data!!.addAll(cacheMesh.cache)
|
||||
data.addAll(cacheMesh.cache)
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,8 +26,9 @@ import de.bixilon.minosoft.gui.rendering.hud.nodes.HUDElement
|
||||
import de.bixilon.minosoft.gui.rendering.hud.nodes.chat.ChatBoxHUDElement
|
||||
import de.bixilon.minosoft.gui.rendering.hud.nodes.debug.HUDSystemDebugNode
|
||||
import de.bixilon.minosoft.gui.rendering.hud.nodes.debug.HUDWorldDebugNode
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.MMath
|
||||
@ -36,12 +37,11 @@ import glm_.glm
|
||||
import glm_.mat4x4.Mat4
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow) : Renderer, ScreenResizeCallback {
|
||||
class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow) : Renderer {
|
||||
private val hudElements: MutableMap<ResourceLocation, Pair<HUDElementProperties, HUDElement>> = mutableMapOf()
|
||||
private val enabledHUDElement: MutableMap<ResourceLocation, Pair<HUDElementProperties, HUDElement>> = mutableMapOf()
|
||||
private val hudShader = Shader(
|
||||
vertexPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_vertex.glsl"),
|
||||
fragmentPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/hud_fragment.glsl"),
|
||||
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "hud"),
|
||||
)
|
||||
lateinit var hudAtlasElements: Map<ResourceLocation, HUDAtlasElement>
|
||||
var orthographicMatrix: Mat4 = Mat4()
|
||||
@ -74,6 +74,13 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
||||
renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.CLOSE) {
|
||||
|
||||
}
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<ScreenResizeEvent> {
|
||||
orthographicMatrix = glm.ortho(-it.screenDimensions.x / 2.0f, it.screenDimensions.x / 2.0f, -it.screenDimensions.y / 2.0f, it.screenDimensions.y / 2.0f)
|
||||
for ((_, hudElement) in hudElements.values) {
|
||||
hudElement.layout.clearChildrenCache()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun registerDefaultElements() {
|
||||
@ -95,9 +102,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
||||
}
|
||||
val hudElement = builder.build(this)
|
||||
hudElement.properties = properties
|
||||
if (hudElement is ScreenResizeCallback) {
|
||||
renderWindow.screenResizeCallbacks.add(hudElement)
|
||||
}
|
||||
val pair = Pair(properties, hudElement)
|
||||
hudElements[builder.RESOURCE_LOCATION] = pair
|
||||
|
||||
@ -124,12 +128,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
||||
fun removeElement(resourceLocation: ResourceLocation) {
|
||||
val element = hudElements[resourceLocation] ?: return
|
||||
|
||||
element.second.let {
|
||||
if (it is ScreenResizeCallback) {
|
||||
renderWindow.screenResizeCallbacks.remove(it)
|
||||
}
|
||||
}
|
||||
|
||||
element.first.toggleKeyBinding?.let {
|
||||
renderWindow.inputHandler.unregisterKeyBinding(it)
|
||||
}
|
||||
@ -150,13 +148,6 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScreenResize(screenDimensions: Vec2i) {
|
||||
orthographicMatrix = glm.ortho(-screenDimensions.x / 2.0f, screenDimensions.x / 2.0f, -screenDimensions.y / 2.0f, screenDimensions.y / 2.0f)
|
||||
for ((_, hudElement) in hudElements.values) {
|
||||
hudElement.layout.clearChildrenCache()
|
||||
}
|
||||
}
|
||||
|
||||
override fun draw() {
|
||||
if (!RenderConstants.RENDER_HUD) {
|
||||
return
|
||||
|
@ -23,11 +23,12 @@ import de.bixilon.minosoft.gui.rendering.hud.elements.input.TextField
|
||||
import de.bixilon.minosoft.gui.rendering.hud.elements.input.TextFieldProperties
|
||||
import de.bixilon.minosoft.gui.rendering.hud.nodes.HUDElement
|
||||
import de.bixilon.minosoft.gui.rendering.hud.nodes.layout.AbsoluteLayout
|
||||
import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), ScreenResizeCallback {
|
||||
class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer) {
|
||||
override val layout = AbsoluteLayout(hudRenderer.renderWindow)
|
||||
private lateinit var inputField: TextField
|
||||
|
||||
@ -48,13 +49,12 @@ class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer), Scr
|
||||
hudRenderer.renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.OPEN_CHAT) {
|
||||
openChat()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScreenResize(screenDimensions: Vec2i) {
|
||||
layout.sizing.minSize.x = screenDimensions.x
|
||||
layout.sizing.maxSize.x = screenDimensions.x
|
||||
inputField.textElement.setProperties.hardWrap = (inputField.textElement.sizing.minSize.x / scale).toInt()
|
||||
layout.apply()
|
||||
hudRenderer.connection.registerEvent(CallbackEventInvoker.of<ScreenResizeEvent> {
|
||||
layout.sizing.minSize.x = it.screenDimensions.x
|
||||
layout.sizing.maxSize.x = it.screenDimensions.x
|
||||
inputField.textElement.setProperties.hardWrap = (inputField.textElement.sizing.minSize.x / scale).toInt()
|
||||
layout.apply()
|
||||
})
|
||||
}
|
||||
|
||||
fun openChat() {
|
||||
|
@ -19,18 +19,18 @@ import de.bixilon.minosoft.gui.rendering.hud.HUDElementProperties
|
||||
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderBuilder
|
||||
import de.bixilon.minosoft.gui.rendering.hud.HUDRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.hud.nodes.properties.NodeAlignment
|
||||
import de.bixilon.minosoft.gui.rendering.util.abstractions.ScreenResizeCallback
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.modding.loading.ModLoader
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.GitInfo
|
||||
import de.bixilon.minosoft.util.SystemInformation
|
||||
import de.bixilon.minosoft.util.UnitFormatter
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2i
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
|
||||
|
||||
class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer), ScreenResizeCallback {
|
||||
class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer) {
|
||||
|
||||
init {
|
||||
layout.sizing.forceAlign = NodeAlignment.RIGHT
|
||||
@ -67,13 +67,13 @@ class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer
|
||||
text("Mods: ${ModLoader.MOD_MAP.size} active, ${hudRenderer.connection.eventListenerSize} listeners")
|
||||
}
|
||||
|
||||
override fun onScreenResize(screenDimensions: Vec2i) {
|
||||
displayText.sText = "Display: ${getScreenDimensions()}"
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
gpuText.sText = "GPU: " + (glGetString(GL_RENDERER) ?: "unknown")
|
||||
gpuVersionText.sText = "Version: " + (glGetString(GL_VERSION) ?: "unknown")
|
||||
|
||||
hudRenderer.connection.registerEvent(CallbackEventInvoker.of<ScreenResizeEvent> {
|
||||
displayText.sText = "Display: ${getScreenDimensions()}"
|
||||
})
|
||||
}
|
||||
|
||||
override fun draw() {
|
||||
|
@ -11,8 +11,13 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.input.camera
|
||||
package de.bixilon.minosoft.gui.rendering.modding.events
|
||||
|
||||
interface FrustumChangeCallback {
|
||||
fun onFrustumChange()
|
||||
}
|
||||
import de.bixilon.minosoft.gui.input.camera.Frustum
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||
|
||||
class FrustumChangeEvent(
|
||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||
val frustum: Frustum,
|
||||
) : RenderEvent(renderWindow)
|
@ -11,11 +11,11 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.util.abstractions
|
||||
package de.bixilon.minosoft.gui.rendering.modding.events
|
||||
|
||||
import glm_.vec2.Vec2i
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.modding.event.events.PlayConnectionEvent
|
||||
|
||||
interface ScreenResizeCallback {
|
||||
|
||||
fun onScreenResize(screenDimensions: Vec2i) {}
|
||||
}
|
||||
abstract class RenderEvent(
|
||||
val renderWindow: RenderWindow,
|
||||
) : PlayConnectionEvent(renderWindow.connection)
|
@ -11,7 +11,7 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.modding.events
|
||||
package de.bixilon.minosoft.gui.rendering.modding.events
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.RenderingStates
|
||||
import de.bixilon.minosoft.modding.event.events.PlayConnectionEvent
|
@ -11,8 +11,14 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.shader
|
||||
package de.bixilon.minosoft.gui.rendering.modding.events
|
||||
|
||||
interface ShaderHolder {
|
||||
val shader: Shader
|
||||
}
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
class ScreenResizeEvent(
|
||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||
val previousScreenDimensions: Vec2i,
|
||||
val screenDimensions: Vec2i,
|
||||
) : RenderEvent(renderWindow)
|
@ -15,7 +15,9 @@ package de.bixilon.minosoft.gui.rendering.shader
|
||||
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.data.assets.AssetsManager
|
||||
import de.bixilon.minosoft.data.commands.CommandStringReader
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||
import de.bixilon.minosoft.gui.rendering.exceptions.ShaderLoadingException
|
||||
import de.bixilon.minosoft.gui.rendering.util.OpenGLUtil
|
||||
import glm_.mat4x4.Mat4
|
||||
@ -30,19 +32,23 @@ import org.lwjgl.opengl.ARBVertexShader.GL_VERTEX_SHADER_ARB
|
||||
import org.lwjgl.opengl.GL11.GL_FALSE
|
||||
import org.lwjgl.opengl.GL43.*
|
||||
import org.lwjgl.system.MemoryUtil
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
class Shader(
|
||||
private val vertexPath: ResourceLocation,
|
||||
private val geometryPath: ResourceLocation? = null,
|
||||
private val fragmentPath: ResourceLocation,
|
||||
private val resourceLocation: ResourceLocation,
|
||||
private val defines: Map<String, Any> = mapOf(),
|
||||
) {
|
||||
lateinit var uniforms: List<String>
|
||||
private set
|
||||
private var programId = 0
|
||||
|
||||
fun load(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER): Int {
|
||||
val vertexShader = createShader(assetsManager, vertexPath, GL_VERTEX_SHADER_ARB, defines)
|
||||
val geometryShader = geometryPath?.let { createShader(assetsManager, it, GL_GEOMETRY_SHADER_ARB, defines) }
|
||||
val fragmentShader = createShader(assetsManager, fragmentPath, GL_FRAGMENT_SHADER_ARB, defines)
|
||||
val uniforms: MutableList<String> = mutableListOf()
|
||||
val pathPrefix = resourceLocation.namespace + ":rendering/shader/" + resourceLocation.path + "/" + resourceLocation.path.replace("/", "_")
|
||||
val vertexShader = createShader(assetsManager, ResourceLocation("$pathPrefix.vsh"), GL_VERTEX_SHADER_ARB, defines, uniforms)!!
|
||||
val geometryShader = createShader(assetsManager, ResourceLocation("$pathPrefix.gsh"), GL_GEOMETRY_SHADER_ARB, defines, uniforms)
|
||||
val fragmentShader = createShader(assetsManager, ResourceLocation("$pathPrefix.fsh"), GL_FRAGMENT_SHADER_ARB, defines, uniforms)!!
|
||||
this.uniforms = uniforms.toList()
|
||||
programId = glCreateProgramObjectARB()
|
||||
|
||||
if (programId.toLong() == MemoryUtil.NULL) {
|
||||
@ -71,13 +77,15 @@ class Shader(
|
||||
}
|
||||
glDeleteShader(fragmentShader)
|
||||
|
||||
val context = Rendering.currentContext!!
|
||||
context.shaders.add(this)
|
||||
return programId
|
||||
}
|
||||
|
||||
fun use(): Shader {
|
||||
if (usedShader !== this) {
|
||||
if (currentShaderInUse !== this) {
|
||||
glUseProgram(programId)
|
||||
usedShader = this
|
||||
currentShaderInUse = this
|
||||
}
|
||||
return this
|
||||
}
|
||||
@ -142,30 +150,42 @@ class Shader(
|
||||
|
||||
|
||||
companion object {
|
||||
private var usedShader: Shader? = null
|
||||
private var currentShaderInUse: Shader? = null
|
||||
|
||||
|
||||
private fun createShader(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER, resourceLocation: ResourceLocation, shaderType: Int, defines: Map<String, Any>): Int {
|
||||
private fun createShader(assetsManager: AssetsManager = Minosoft.MINOSOFT_ASSETS_MANAGER, resourceLocation: ResourceLocation, shaderType: Int, defines: Map<String, Any>, uniforms: MutableList<String>): Int? {
|
||||
val shaderId = glCreateShaderObjectARB(shaderType)
|
||||
if (shaderId.toLong() == MemoryUtil.NULL) {
|
||||
throw ShaderLoadingException()
|
||||
}
|
||||
val total = StringBuilder()
|
||||
val lines = assetsManager.readStringAsset(resourceLocation).lines()
|
||||
val lines = try {
|
||||
assetsManager.readStringAsset(resourceLocation).lines()
|
||||
} catch (exception: FileNotFoundException) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (line in lines) {
|
||||
total.append(line)
|
||||
total.append('\n')
|
||||
if (line.startsWith("#version")) {
|
||||
|
||||
// add all defines
|
||||
total.append('\n')
|
||||
for ((define, value) in defines) {
|
||||
total.append("#define ")
|
||||
total.append(define)
|
||||
total.append(' ')
|
||||
total.append(value)
|
||||
val reader = CommandStringReader(line)
|
||||
when {
|
||||
line.startsWith("#version") -> {
|
||||
// add all defines
|
||||
total.append('\n')
|
||||
for ((define, value) in defines) {
|
||||
total.append("#define ")
|
||||
total.append(define)
|
||||
total.append(' ')
|
||||
total.append(value)
|
||||
total.append('\n')
|
||||
}
|
||||
}
|
||||
line.startsWith("uniform ") -> { // ToDo: Packed in layout
|
||||
reader.readUnquotedString() // "uniform"
|
||||
reader.skipWhitespaces()
|
||||
reader.readUnquotedString() // datatype
|
||||
reader.skipWhitespaces()
|
||||
uniforms.add(reader.readString()) // uniform name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,6 @@ import org.lwjgl.opengl.GL20.glVertexAttribPointer
|
||||
class SkyMesh : Mesh(initialCacheSize = 6 * 2 * 3 * FLOATS_PER_VERTEX) {
|
||||
|
||||
fun addVertex(position: Vec3) {
|
||||
val data = data!!
|
||||
|
||||
data.addAll(floatArrayOf(
|
||||
position.x,
|
||||
position.y,
|
||||
|
@ -18,7 +18,6 @@ import de.bixilon.minosoft.gui.rendering.RenderBuilder
|
||||
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.ShaderHolder
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
@ -26,39 +25,35 @@ import org.lwjgl.opengl.GL11.*
|
||||
class SkyRenderer(
|
||||
private val connection: PlayConnection,
|
||||
val renderWindow: RenderWindow,
|
||||
) : Renderer, ShaderHolder {
|
||||
) : Renderer {
|
||||
private var lastMatrixUpdate = System.currentTimeMillis()
|
||||
override val shader = Shader(
|
||||
vertexPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/sky_vertex.glsl"),
|
||||
fragmentPath = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "rendering/shader/sky_fragment.glsl"),
|
||||
private val skyColorShader = Shader(
|
||||
resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "sky/color"),
|
||||
)
|
||||
private val mesh = SkyMesh()
|
||||
|
||||
init {
|
||||
mesh.data!!.addAll(VERTICES)
|
||||
mesh.data.addAll(VERTICES)
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
shader.load()
|
||||
skyColorShader.load()
|
||||
|
||||
mesh.load()
|
||||
}
|
||||
|
||||
override fun postInit() {
|
||||
}
|
||||
|
||||
private fun setShaderMatrix() {
|
||||
if (lastMatrixUpdate == renderWindow.inputHandler.camera.lastMatrixChange) {
|
||||
return
|
||||
}
|
||||
shader.use().setMat4("skyViewProjectionMatrix", renderWindow.inputHandler.camera.projectionMatrix * renderWindow.inputHandler.camera.viewMatrix.toMat3().toMat4())
|
||||
skyColorShader.use().setMat4("skyViewProjectionMatrix", renderWindow.inputHandler.camera.projectionMatrix * renderWindow.inputHandler.camera.viewMatrix.toMat3().toMat4())
|
||||
lastMatrixUpdate = renderWindow.inputHandler.camera.lastMatrixChange
|
||||
}
|
||||
|
||||
|
||||
override fun draw() {
|
||||
glDepthFunc(GL_LEQUAL)
|
||||
shader.use()
|
||||
skyColorShader.use()
|
||||
setShaderMatrix()
|
||||
mesh.draw()
|
||||
glDepthFunc(GL_LESS)
|
||||
|
@ -21,7 +21,13 @@ import org.lwjgl.opengl.GL30.*
|
||||
abstract class Mesh(
|
||||
initialCacheSize: Int = 10000,
|
||||
) {
|
||||
var data: ArrayFloatList? = ArrayFloatList(initialCacheSize)
|
||||
private var _data: ArrayFloatList? = ArrayFloatList(initialCacheSize)
|
||||
var data: ArrayFloatList
|
||||
get() = _data!!
|
||||
set(value) {
|
||||
_data = value
|
||||
}
|
||||
|
||||
private var vao: Int = -1
|
||||
private var vbo: Int = -1
|
||||
var trianglesCount: Int = -1
|
||||
@ -36,16 +42,16 @@ abstract class Mesh(
|
||||
protected fun initializeBuffers(floatsPerVertex: Int) {
|
||||
check(state == MeshStates.PREPARING) { "Mesh already loaded: $state" }
|
||||
|
||||
trianglesCount = data!!.size / floatsPerVertex
|
||||
trianglesCount = data.size / floatsPerVertex
|
||||
vao = glGenVertexArrays()
|
||||
vbo = glGenBuffers()
|
||||
glBindVertexArray(vao)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo)
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, data!!.toArray(), GL_STATIC_DRAW)
|
||||
glBufferData(GL_ARRAY_BUFFER, data.toArray(), GL_STATIC_DRAW)
|
||||
|
||||
state = MeshStates.LOADED
|
||||
data = null
|
||||
_data = null
|
||||
}
|
||||
|
||||
protected fun unbind() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user