mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-22 03:52:50 -04:00
wip: abstract glfw window
This commit is contained in:
parent
7ff391f703
commit
b7fa34dc24
@ -17,6 +17,7 @@ import com.google.gson.JsonObject
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.FluidFillable
|
||||
import de.bixilon.minosoft.data.registries.fluid.FlowableFluid
|
||||
import de.bixilon.minosoft.data.registries.fluid.Fluid
|
||||
import de.bixilon.minosoft.data.registries.versions.Registries
|
||||
@ -49,6 +50,10 @@ class WaterFluid(
|
||||
if (other.properties[BlockProperties.WATERLOGGED] == true) {
|
||||
return true
|
||||
}
|
||||
if (other.block is FluidFillable && resourceLocation == other.block.fluid) {
|
||||
return true
|
||||
}
|
||||
|
||||
return super.matches(other)
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ data class Version(
|
||||
registries.load(this, pixlyzerData)
|
||||
latch.dec()
|
||||
if (pixlyzerData.size() > 0) {
|
||||
Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.INFO) { "Loaded registries for $this (${versionName} in ${System.currentTimeMillis() - startTime}ms" }
|
||||
Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.INFO) { "Loaded registries for $this $versionName in ${System.currentTimeMillis() - startTime}ms" }
|
||||
} else {
|
||||
Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.WARN) { "Could not load registries for $this (${versionName}. Some features might not work." }
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
package de.bixilon.minosoft.gui.rendering
|
||||
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.config.StaticConfiguration
|
||||
import de.bixilon.minosoft.config.config.game.controls.KeyBindingsNames
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.ChunkBorderRenderer
|
||||
@ -27,12 +26,13 @@ import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLike
|
||||
import de.bixilon.minosoft.gui.rendering.hud.atlas.TextureLikeTexture
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.RenderWindowInputHandler
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.RenderingStateChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
||||
import de.bixilon.minosoft.gui.rendering.system.opengl.OpenGLRenderSystem
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.GLFWWindow
|
||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
||||
import de.bixilon.minosoft.gui.rendering.util.ScreenshotTaker
|
||||
@ -49,28 +49,32 @@ import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2i
|
||||
import org.lwjgl.glfw.*
|
||||
import org.lwjgl.glfw.Callbacks
|
||||
import org.lwjgl.glfw.GLFW.*
|
||||
import org.lwjgl.glfw.GLFWWindowFocusCallback
|
||||
import org.lwjgl.glfw.GLFWWindowIconifyCallback
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
import org.lwjgl.system.MemoryStack
|
||||
import org.lwjgl.system.MemoryUtil
|
||||
|
||||
class RenderWindow(
|
||||
val connection: PlayConnection,
|
||||
val rendering: Rendering,
|
||||
) {
|
||||
val renderSystem: RenderSystem = OpenGLRenderSystem()
|
||||
val window = GLFWWindow(connection)
|
||||
val renderSystem: RenderSystem = OpenGLRenderSystem(this)
|
||||
var initialized = false
|
||||
private set
|
||||
private lateinit var renderThread: Thread
|
||||
val renderStats = RenderStats()
|
||||
var screenDimensions = Vec2i(900, 500)
|
||||
private set
|
||||
var screenDimensionsF = Vec2(screenDimensions)
|
||||
private set
|
||||
|
||||
@Deprecated(message = "", replaceWith = ReplaceWith("window.size"))
|
||||
val screenDimensions
|
||||
get() = window.size
|
||||
|
||||
@Deprecated(message = "", replaceWith = ReplaceWith("window.sizef"))
|
||||
val screenDimensionsF: Vec2
|
||||
get() = window.sizef
|
||||
val inputHandler = RenderWindowInputHandler(this)
|
||||
|
||||
var windowId = 0L
|
||||
private var deltaFrameTime = 0.0
|
||||
|
||||
private var lastFrame = 0.0
|
||||
@ -132,58 +136,16 @@ class RenderWindow(
|
||||
renderThread = Thread.currentThread()
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Creating window..." }
|
||||
val stopwatch = Stopwatch()
|
||||
// Setup an error callback. The default implementation
|
||||
// will print the error message in System.err.
|
||||
GLFWErrorCallback.createPrint(System.err).set()
|
||||
|
||||
// Initialize Most GLFW functions will not work before doing this.
|
||||
check(glfwInit()) { "Unable to initialize GLFW" }
|
||||
window.init()
|
||||
|
||||
// Configure GLFW
|
||||
glfwDefaultWindowHints() // optional, the current window hints are already the default
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3)
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE) // the window will stay hidden after creation
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE) // the window will be resizable
|
||||
|
||||
// Create the window
|
||||
windowId = glfwCreateWindow(screenDimensions.x, screenDimensions.y, "Minosoft", MemoryUtil.NULL, MemoryUtil.NULL)
|
||||
if (windowId == MemoryUtil.NULL) {
|
||||
glfwTerminate()
|
||||
throw RuntimeException("Failed to create the GLFW window")
|
||||
}
|
||||
inputHandler.camera.init(this)
|
||||
|
||||
tintColorCalculator.init(connection.assetsManager)
|
||||
|
||||
|
||||
|
||||
if (!StaticConfiguration.DEBUG_MODE) {
|
||||
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
|
||||
}
|
||||
glfwSetWindowSizeLimits(windowId, 100, 100, GLFW_DONT_CARE, GLFW_DONT_CARE)
|
||||
|
||||
|
||||
MemoryStack.stackPush().let { stack ->
|
||||
val pWidth = stack.mallocInt(1)
|
||||
val pHeight = stack.mallocInt(1)
|
||||
|
||||
// Get the window size passed to glfwCreateWindow
|
||||
glfwGetWindowSize(windowId, pWidth, pHeight)
|
||||
|
||||
// Get the resolution of the primary monitor
|
||||
val videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor())!!
|
||||
|
||||
// Center the window
|
||||
glfwSetWindowPos(windowId, (videoMode.width() - pWidth[0]) / 2, (videoMode.height() - pHeight[0]) / 2)
|
||||
}
|
||||
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Creating context (${stopwatch.labTime()})..." }
|
||||
// Make the OpenGL context current
|
||||
glfwMakeContextCurrent(windowId)
|
||||
// Enable v-sync
|
||||
glfwSwapInterval(Minosoft.config.config.game.other.swapInterval)
|
||||
|
||||
renderSystem.init()
|
||||
|
||||
@ -213,7 +175,6 @@ class RenderWindow(
|
||||
renderer.init()
|
||||
}
|
||||
|
||||
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Preloading textures (${stopwatch.labTime()})..." }
|
||||
textures.preLoad(connection.assetsManager)
|
||||
font.loadAtlas()
|
||||
@ -228,17 +189,8 @@ class RenderWindow(
|
||||
|
||||
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Registering glfw callbacks (${stopwatch.labTime()})..." }
|
||||
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)
|
||||
connection.fireEvent(ScreenResizeEvent(previousScreenDimensions = previousSize, screenDimensions = screenDimensions))
|
||||
}
|
||||
})
|
||||
|
||||
glfwSetWindowFocusCallback(windowId, object : GLFWWindowFocusCallback() {
|
||||
glfwSetWindowFocusCallback(window.window, object : GLFWWindowFocusCallback() {
|
||||
override fun invoke(window: Long, focused: Boolean) {
|
||||
setRenderStatus(if (focused) {
|
||||
RenderingStates.RUNNING
|
||||
@ -248,7 +200,7 @@ class RenderWindow(
|
||||
}
|
||||
})
|
||||
|
||||
glfwSetWindowIconifyCallback(windowId, object : GLFWWindowIconifyCallback() {
|
||||
glfwSetWindowIconifyCallback(window.window, object : GLFWWindowIconifyCallback() {
|
||||
override fun invoke(window: Long, iconified: Boolean) {
|
||||
setRenderStatus(if (iconified) {
|
||||
RenderingStates.PAUSED
|
||||
@ -257,18 +209,13 @@ class RenderWindow(
|
||||
})
|
||||
}
|
||||
})
|
||||
glfwSetKeyCallback(this.windowId, inputHandler::keyInput)
|
||||
glfwSetMouseButtonCallback(this.windowId, inputHandler::mouseKeyInput)
|
||||
|
||||
glfwSetCharCallback(windowId, inputHandler::charInput)
|
||||
glfwSetCursorPosCallback(windowId, inputHandler::mouseMove)
|
||||
|
||||
|
||||
inputHandler.init()
|
||||
registerGlobalKeyCombinations()
|
||||
|
||||
|
||||
connection.fireEvent(ScreenResizeEvent(previousScreenDimensions = Vec2i(0, 0), screenDimensions = screenDimensions))
|
||||
connection.fireEvent(ResizeWindowEvent(previousSize = Vec2i(0, 0), size = window.size))
|
||||
|
||||
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Rendering is fully prepared in ${stopwatch.totalTime()}" }
|
||||
@ -276,7 +223,7 @@ class RenderWindow(
|
||||
latch.dec()
|
||||
latch.await()
|
||||
this.latch.await()
|
||||
glfwShowWindow(windowId)
|
||||
window.visible = true
|
||||
Log.log(LogMessageType.RENDERING_GENERAL) { "Showing window after ${stopwatch.totalTime()}" }
|
||||
}
|
||||
|
||||
@ -290,7 +237,7 @@ class RenderWindow(
|
||||
sendDebugMessage("Toggled polygon mode!")
|
||||
}
|
||||
|
||||
inputHandler.registerKeyCallback(KeyBindingsNames.QUIT_RENDERING) { glfwSetWindowShouldClose(windowId, true) }
|
||||
inputHandler.registerKeyCallback(KeyBindingsNames.QUIT_RENDERING) { glfwSetWindowShouldClose(window.window, true) }
|
||||
inputHandler.registerKeyCallback(KeyBindingsNames.TAKE_SCREENSHOT) { screenshotTaker.takeScreenshot() }
|
||||
|
||||
inputHandler.registerKeyCallback(KeyBindingsNames.DEBUG_PAUSE_INCOMING_PACKETS) {
|
||||
@ -305,7 +252,7 @@ class RenderWindow(
|
||||
|
||||
fun startLoop() {
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Starting loop" }
|
||||
while (!glfwWindowShouldClose(windowId)) {
|
||||
while (!glfwWindowShouldClose(window.window)) {
|
||||
if (connection.wasConnected) {
|
||||
break
|
||||
}
|
||||
@ -346,7 +293,7 @@ class RenderWindow(
|
||||
renderStats.endDraw()
|
||||
|
||||
|
||||
glfwSwapBuffers(windowId)
|
||||
glfwSwapBuffers(window.window)
|
||||
glfwPollEvents()
|
||||
inputHandler.draw(deltaFrameTime)
|
||||
|
||||
@ -357,12 +304,12 @@ class RenderWindow(
|
||||
RenderingStates.SLOW -> Thread.sleep(100L)
|
||||
RenderingStates.RUNNING, RenderingStates.PAUSED -> {
|
||||
}
|
||||
RenderingStates.STOPPED -> glfwSetWindowShouldClose(windowId, true)
|
||||
RenderingStates.STOPPED -> glfwSetWindowShouldClose(window.window, true)
|
||||
}
|
||||
renderStats.endFrame()
|
||||
|
||||
if (RenderConstants.SHOW_FPS_IN_WINDOW_TITLE) {
|
||||
glfwSetWindowTitle(windowId, "Minosoft | FPS: ${renderStats.fpsLastSecond}")
|
||||
glfwSetWindowTitle(window.window, "Minosoft | FPS: ${renderStats.fpsLastSecond}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -370,8 +317,8 @@ class RenderWindow(
|
||||
fun exit() {
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Destroying render window..." }
|
||||
// Free the window callbacks and destroy the window
|
||||
Callbacks.glfwFreeCallbacks(windowId)
|
||||
glfwDestroyWindow(windowId)
|
||||
Callbacks.glfwFreeCallbacks(window.window)
|
||||
glfwDestroyWindow(window.window)
|
||||
|
||||
// Terminate GLFW and free the error callback
|
||||
glfwTerminate()
|
||||
@ -404,7 +351,7 @@ class RenderWindow(
|
||||
}
|
||||
|
||||
fun getClipboardText(): String {
|
||||
return glfwGetClipboardString(windowId) ?: ""
|
||||
return glfwGetClipboardString(window.window) ?: ""
|
||||
}
|
||||
|
||||
fun assertOnRenderThread() {
|
||||
|
@ -27,7 +27,7 @@ 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.modding.events.ResizeWindowEvent
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
@ -76,8 +76,8 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> {
|
||||
orthographicMatrix = glm.ortho(-it.size.x / 2.0f, it.size.x / 2.0f, -it.size.y / 2.0f, it.size.y / 2.0f)
|
||||
for ((_, hudElement) in hudElements.values) {
|
||||
hudElement.layout.clearChildrenCache()
|
||||
}
|
||||
@ -178,7 +178,7 @@ class HUDRenderer(val connection: PlayConnection, val renderWindow: RenderWindow
|
||||
realSize.x = MMath.clamp(realSize.x, hudElement.layout.sizing.minSize.x, hudElement.layout.sizing.maxSize.x)
|
||||
realSize.y = MMath.clamp(realSize.y, hudElement.layout.sizing.minSize.y, hudElement.layout.sizing.maxSize.y)
|
||||
|
||||
val elementStart = getRealPosition(realSize, elementProperties, renderWindow.screenDimensions)
|
||||
val elementStart = getRealPosition(realSize, elementProperties, renderWindow.window.size)
|
||||
|
||||
hudElement.layout.checkCache(elementStart, realScaleFactor, orthographicMatrix, 0)
|
||||
tempMesh.addCacheMesh(hudElement.layout.cache)
|
||||
|
@ -23,7 +23,7 @@ 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.modding.events.ScreenResizeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2i
|
||||
@ -49,9 +49,9 @@ class ChatBoxHUDElement(hudRenderer: HUDRenderer) : HUDElement(hudRenderer) {
|
||||
hudRenderer.renderWindow.inputHandler.registerKeyCallback(KeyBindingsNames.OPEN_CHAT) {
|
||||
openChat()
|
||||
}
|
||||
hudRenderer.connection.registerEvent(CallbackEventInvoker.of<ScreenResizeEvent> {
|
||||
layout.sizing.minSize.x = it.screenDimensions.x
|
||||
layout.sizing.maxSize.x = it.screenDimensions.x
|
||||
hudRenderer.connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> {
|
||||
layout.sizing.minSize.x = it.size.x
|
||||
layout.sizing.maxSize.x = it.size.x
|
||||
inputField.textElement.setProperties.hardWrap = (inputField.textElement.sizing.minSize.x / scale).toInt()
|
||||
layout.apply()
|
||||
})
|
||||
|
@ -19,7 +19,7 @@ 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.modding.events.ScreenResizeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.modding.loading.ModLoader
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
@ -74,7 +74,7 @@ class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer
|
||||
gpuText.sText = "GPU: " + (glGetString(GL_RENDERER) ?: "unknown")
|
||||
gpuVersionText.sText = "Version: " + (glGetString(GL_VERSION) ?: "unknown")
|
||||
|
||||
hudRenderer.connection.registerEvent(CallbackEventInvoker.of<ScreenResizeEvent> {
|
||||
hudRenderer.connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> {
|
||||
displayText.sText = "Display: ${getScreenDimensions()}"
|
||||
})
|
||||
}
|
||||
@ -123,7 +123,7 @@ class HUDSystemDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer
|
||||
}
|
||||
|
||||
private fun getScreenDimensions(): String {
|
||||
return "${hudRenderer.renderWindow.screenDimensions.x}x${hudRenderer.renderWindow.screenDimensions.y}"
|
||||
return "${hudRenderer.renderWindow.window.size.x}x${hudRenderer.renderWindow.window.size.y}"
|
||||
}
|
||||
|
||||
companion object : HUDRenderBuilder<HUDSystemDebugNode> {
|
||||
|
@ -22,7 +22,7 @@ import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.CameraPositionChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.FrustumChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ScreenResizeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
||||
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.floor
|
||||
@ -35,6 +35,7 @@ import glm_.func.sin
|
||||
import glm_.glm
|
||||
import glm_.mat4x4.Mat4d
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2d
|
||||
import glm_.vec3.Vec3d
|
||||
|
||||
class Camera(
|
||||
@ -44,8 +45,7 @@ class Camera(
|
||||
private var mouseSensitivity = Minosoft.getConfig().config.game.camera.moseSensitivity
|
||||
val entity: LocalPlayerEntity
|
||||
get() = connection.player
|
||||
private var lastMouseX = 0.0
|
||||
private var lastMouseY = 0.0
|
||||
private var lastMousePosition: Vec2d = Vec2d(0.0, 0.0)
|
||||
private var zoom = 0.0f
|
||||
|
||||
var cameraFront = Vec3d(0.0, 0.0, -1.0)
|
||||
@ -65,7 +65,7 @@ class Camera(
|
||||
|
||||
var viewMatrix = calculateViewMatrix()
|
||||
private set
|
||||
var projectionMatrix = calculateProjectionMatrix(renderWindow.screenDimensionsF)
|
||||
var projectionMatrix = calculateProjectionMatrix(renderWindow.window.sizef)
|
||||
private set
|
||||
var viewProjectionMatrix = projectionMatrix * viewMatrix
|
||||
private set
|
||||
@ -74,24 +74,21 @@ class Camera(
|
||||
val frustum: Frustum = Frustum(this)
|
||||
|
||||
|
||||
fun mouseCallback(xPos: Double, yPos: Double) {
|
||||
var xOffset = xPos - this.lastMouseX
|
||||
var yOffset = yPos - this.lastMouseY
|
||||
lastMouseX = xPos
|
||||
lastMouseY = yPos
|
||||
fun mouseCallback(position: Vec2d) {
|
||||
val delta = position - lastMousePosition
|
||||
lastMousePosition = position
|
||||
if (renderWindow.inputHandler.currentKeyConsumer != null) {
|
||||
return
|
||||
}
|
||||
xOffset *= mouseSensitivity
|
||||
yOffset *= mouseSensitivity
|
||||
var yaw = xOffset + entity.rotation.headYaw
|
||||
delta *= mouseSensitivity
|
||||
var yaw = delta.x + entity.rotation.headYaw
|
||||
if (yaw > 180) {
|
||||
yaw -= 360
|
||||
} else if (yaw < -180) {
|
||||
yaw += 360
|
||||
}
|
||||
yaw %= 180
|
||||
val pitch = glm.clamp(yOffset + entity.rotation.pitch, -89.9, 89.9)
|
||||
val pitch = glm.clamp(delta.y + entity.rotation.pitch, -89.9, 89.9)
|
||||
entity.rotation = EntityRotation(yaw, pitch)
|
||||
setRotation(yaw, pitch)
|
||||
}
|
||||
@ -111,14 +108,14 @@ class Camera(
|
||||
KeyBindingsNames.MOVE_TOGGLE_FLY,
|
||||
)
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<ScreenResizeEvent> { recalculateViewProjectionMatrix() })
|
||||
connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> { recalculateViewProjectionMatrix() })
|
||||
frustum.recalculate()
|
||||
connection.fireEvent(FrustumChangeEvent(renderWindow, frustum))
|
||||
}
|
||||
|
||||
private fun recalculateViewProjectionMatrix() {
|
||||
viewMatrix = calculateViewMatrix()
|
||||
projectionMatrix = calculateProjectionMatrix(renderWindow.screenDimensionsF)
|
||||
projectionMatrix = calculateProjectionMatrix(renderWindow.window.sizef)
|
||||
viewProjectionMatrix = projectionMatrix * viewMatrix
|
||||
connection.fireEvent(CameraMatrixChangeEvent(
|
||||
renderWindow = renderWindow,
|
||||
|
@ -24,10 +24,12 @@ import de.bixilon.minosoft.gui.rendering.hud.elements.input.KeyConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.input.LeftClickHandler
|
||||
import de.bixilon.minosoft.gui.rendering.input.RightClickHandler
|
||||
import de.bixilon.minosoft.gui.rendering.input.camera.Camera
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.MouseMoveEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.RawCharInputEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.RawKeyInputEvent
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import org.lwjgl.glfw.GLFW.*
|
||||
|
||||
class RenderWindowInputHandler(
|
||||
@ -53,7 +55,7 @@ class RenderWindowInputHandler(
|
||||
} else {
|
||||
GLFW_CURSOR_NORMAL
|
||||
}
|
||||
glfwSetInputMode(renderWindow.windowId, GLFW_CURSOR, newCursorMode)
|
||||
glfwSetInputMode(renderWindow.window.window, GLFW_CURSOR, newCursorMode)
|
||||
renderWindow.sendDebugMessage("Toggled mouse catch!")
|
||||
}
|
||||
}
|
||||
@ -61,35 +63,28 @@ class RenderWindowInputHandler(
|
||||
fun init() {
|
||||
rightClickHandler.init()
|
||||
leftClickHandler.init()
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<RawCharInputEvent> { charInput(it.char) })
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<RawKeyInputEvent> { keyInput(it.keyCode, it.keyChangeType) })
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<MouseMoveEvent> { camera.mouseCallback(it.position) })
|
||||
}
|
||||
|
||||
|
||||
var currentKeyConsumer: KeyConsumer? = null
|
||||
|
||||
fun mouseKeyInput(windowId: Long, button: Int, action: Int, modifierKey: Int) {
|
||||
keyInput(windowId, button, 0, action, modifierKey)
|
||||
}
|
||||
|
||||
fun keyInput(windowId: Long, key: Int, char: Int, action: Int, modifierKey: Int) {
|
||||
if (windowId != renderWindow.windowId) {
|
||||
return
|
||||
}
|
||||
val keyCode = KeyCodes.KEY_CODE_GLFW_ID_MAP[key] ?: KeyCodes.KEY_UNKNOWN
|
||||
|
||||
val keyDown = when (action) {
|
||||
GLFW_PRESS -> {
|
||||
private fun keyInput(keyCode: KeyCodes, keyChangeType: KeyChangeTypes) {
|
||||
val keyDown = when (keyChangeType) {
|
||||
KeyChangeTypes.PRESS -> {
|
||||
currentKeyConsumer?.keyInput(keyCode)
|
||||
true
|
||||
}
|
||||
GLFW_RELEASE -> false
|
||||
GLFW_REPEAT -> {
|
||||
KeyChangeTypes.RELEASE -> false
|
||||
KeyChangeTypes.REPEAT -> {
|
||||
currentKeyConsumer?.keyInput(keyCode)
|
||||
return
|
||||
}
|
||||
else -> {
|
||||
Log.log(LogMessageType.RENDERING_GENERAL, LogLevels.WARN) { "Unknown glfw action $action" }
|
||||
return
|
||||
}
|
||||
}
|
||||
val currentTime = System.currentTimeMillis()
|
||||
|
||||
@ -219,10 +214,7 @@ class RenderWindowInputHandler(
|
||||
}
|
||||
}
|
||||
|
||||
fun charInput(windowId: Long, char: Int) {
|
||||
if (windowId != renderWindow.windowId) {
|
||||
return
|
||||
}
|
||||
private fun charInput(char: Int) {
|
||||
if (skipNextCharPress) {
|
||||
skipNextCharPress = false
|
||||
return
|
||||
@ -230,13 +222,6 @@ class RenderWindowInputHandler(
|
||||
currentKeyConsumer?.charInput(char.toChar())
|
||||
}
|
||||
|
||||
fun mouseMove(windowId: Long, xPos: Double, yPos: Double) {
|
||||
if (windowId != renderWindow.windowId) {
|
||||
return
|
||||
}
|
||||
camera.mouseCallback(xPos, yPos)
|
||||
}
|
||||
|
||||
fun registerKeyCallback(resourceLocation: ResourceLocation, callback: ((keyDown: Boolean) -> Unit)) {
|
||||
val keyBinding = Minosoft.getConfig().config.game.controls.keyBindings.entries[resourceLocation] ?: return
|
||||
val callbackPair = keyBindingCallbacks.getOrPut(resourceLocation) { KeyBindingCallbackPair(keyBinding) }
|
||||
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.modding.events
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||
import glm_.vec2.Vec2d
|
||||
|
||||
class MouseMoveEvent(
|
||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||
position: Vec2d,
|
||||
) : RenderEvent(renderWindow) {
|
||||
val position: Vec2d = position
|
||||
get() = Vec2d(field)
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.modding.events
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||
|
||||
class RawCharInputEvent(
|
||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||
val char: Int,
|
||||
) : RenderEvent(renderWindow)
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.modding.events
|
||||
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes
|
||||
|
||||
class RawKeyInputEvent(
|
||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||
val keyCode: KeyCodes,
|
||||
val keyChangeType: KeyChangeTypes,
|
||||
) : RenderEvent(renderWindow)
|
@ -17,8 +17,8 @@ import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.Rendering
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
class ScreenResizeEvent(
|
||||
class ResizeWindowEvent(
|
||||
renderWindow: RenderWindow = Rendering.currentContext!!,
|
||||
val previousScreenDimensions: Vec2i,
|
||||
val screenDimensions: Vec2i,
|
||||
val previousSize: Vec2i,
|
||||
val size: Vec2i,
|
||||
) : RenderEvent(renderWindow)
|
@ -13,17 +13,22 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.system.opengl
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderingCapabilities
|
||||
import de.bixilon.minosoft.modding.event.CallbackEventInvoker
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedSetOf
|
||||
import org.lwjgl.opengl.GL
|
||||
import org.lwjgl.opengl.GL20.*
|
||||
|
||||
class OpenGLRenderSystem : RenderSystem {
|
||||
class OpenGLRenderSystem(
|
||||
private val renderWindow: RenderWindow,
|
||||
) : RenderSystem {
|
||||
val shaders: MutableMap<Shader, Int> = synchronizedMapOf() // ToDo
|
||||
private val capabilities: MutableSet<RenderingCapabilities> = synchronizedSetOf()
|
||||
var blendingSource = BlendingFunctions.ONE
|
||||
@ -44,6 +49,12 @@ class OpenGLRenderSystem : RenderSystem {
|
||||
|
||||
override fun init() {
|
||||
GL.createCapabilities()
|
||||
|
||||
renderWindow.connection.registerEvent(CallbackEventInvoker.of<ResizeWindowEvent> {
|
||||
renderWindow.queue += {
|
||||
glViewport(0, 0, it.size.x, it.size.y)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun enable(capability: RenderingCapabilities) {
|
||||
|
@ -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.system.window
|
||||
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.config.StaticConfiguration
|
||||
import glm_.vec2.Vec2
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
interface BaseWindow {
|
||||
var size: Vec2i
|
||||
val sizef: Vec2
|
||||
get() = Vec2(size)
|
||||
var minSize: Vec2i
|
||||
var maxSize: Vec2i
|
||||
|
||||
var visible: Boolean
|
||||
var resizable: Boolean
|
||||
|
||||
var swapInterval: Int
|
||||
|
||||
var cursorMode: CursorModes
|
||||
|
||||
fun init() {
|
||||
resizable = true
|
||||
swapInterval = Minosoft.config.config.game.other.swapInterval
|
||||
|
||||
if (!StaticConfiguration.DEBUG_MODE) {
|
||||
cursorMode = CursorModes.DISABLED
|
||||
}
|
||||
size = DEFAULT_WINDOW_SIZE
|
||||
minSize = DEFAULT_MINIMUM_WINDOW_SIZE
|
||||
maxSize = DEFAULT_MAXIMUM_WINDOW_SIZE
|
||||
}
|
||||
|
||||
fun close()
|
||||
|
||||
|
||||
companion object {
|
||||
val DEFAULT_WINDOW_SIZE: Vec2i
|
||||
get() = Vec2i(900, 500)
|
||||
val DEFAULT_MINIMUM_WINDOW_SIZE: Vec2i
|
||||
get() = Vec2i(100, 100)
|
||||
val DEFAULT_MAXIMUM_WINDOW_SIZE: Vec2i
|
||||
get() = Vec2i(-1, -1)
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.window
|
||||
|
||||
enum class CursorModes {
|
||||
NORMAL,
|
||||
HIDDEN,
|
||||
DISABLED,
|
||||
;
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* 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.window
|
||||
|
||||
import de.bixilon.minosoft.config.key.KeyCodes
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.MouseMoveEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.RawCharInputEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.RawKeyInputEvent
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.ResizeWindowEvent
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.BaseWindow.Companion.DEFAULT_MAXIMUM_WINDOW_SIZE
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.BaseWindow.Companion.DEFAULT_MINIMUM_WINDOW_SIZE
|
||||
import de.bixilon.minosoft.gui.rendering.system.window.BaseWindow.Companion.DEFAULT_WINDOW_SIZE
|
||||
import de.bixilon.minosoft.modding.event.EventMaster
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import glm_.vec2.Vec2d
|
||||
import glm_.vec2.Vec2i
|
||||
import org.lwjgl.glfw.GLFW.*
|
||||
import org.lwjgl.glfw.GLFWErrorCallback
|
||||
import org.lwjgl.system.MemoryUtil
|
||||
|
||||
class GLFWWindow(
|
||||
private val eventMaster: EventMaster,
|
||||
) : BaseWindow {
|
||||
@Deprecated("Will be private soon")
|
||||
var window = -1L
|
||||
|
||||
override var cursorMode: CursorModes = CursorModes.NORMAL
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
glfwSetInputMode(window, GLFW_CURSOR, value.glfw)
|
||||
field = value
|
||||
}
|
||||
|
||||
private var _size = DEFAULT_WINDOW_SIZE
|
||||
|
||||
override var size: Vec2i
|
||||
get() = _size
|
||||
set(value) {
|
||||
glfwSetWindowSize(window, value.x, value.y)
|
||||
_size = size
|
||||
}
|
||||
|
||||
override var minSize: Vec2i = DEFAULT_MINIMUM_WINDOW_SIZE
|
||||
set(value) {
|
||||
glfwSetWindowSizeLimits(window, value.x, value.y, maxSize.x, maxSize.y)
|
||||
field = value
|
||||
}
|
||||
|
||||
override var maxSize: Vec2i = DEFAULT_MAXIMUM_WINDOW_SIZE
|
||||
set(value) {
|
||||
glfwSetWindowSizeLimits(window, minSize.x, minSize.y, value.x, value.y)
|
||||
field = value
|
||||
}
|
||||
|
||||
override var visible: Boolean = false
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
when (value) {
|
||||
true -> glfwShowWindow(window)
|
||||
false -> glfwHideWindow(window)
|
||||
}
|
||||
field = value
|
||||
}
|
||||
|
||||
override var resizable: Boolean = true
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
glfwWindowHint(GLFW_RESIZABLE, value.glfw)
|
||||
field = value
|
||||
}
|
||||
|
||||
override var swapInterval: Int = -1
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
glfwSwapInterval(value)
|
||||
field = value
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
GLFWErrorCallback.createPrint(System.err).set()
|
||||
check(glfwInit()) { "Unable to initialize GLFW" }
|
||||
|
||||
glfwDefaultWindowHints()
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3)
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE)
|
||||
glfwWindowHint(GLFW_VISIBLE, false.glfw)
|
||||
|
||||
|
||||
window = glfwCreateWindow(size.x, size.y, "Minosoft", MemoryUtil.NULL, MemoryUtil.NULL)
|
||||
if (window == MemoryUtil.NULL) {
|
||||
close()
|
||||
throw RuntimeException("Failed to create the GLFW window")
|
||||
}
|
||||
|
||||
|
||||
val videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor())!!
|
||||
|
||||
glfwSetWindowPos(window, (videoMode.width() - size.x) / 2, (videoMode.height() - size.y) / 2)
|
||||
|
||||
glfwMakeContextCurrent(window)
|
||||
|
||||
|
||||
glfwSetKeyCallback(window, this::keyInput)
|
||||
glfwSetMouseButtonCallback(window, this::mouseKeyInput)
|
||||
|
||||
glfwSetCharCallback(window, this::charInput)
|
||||
glfwSetCursorPosCallback(window, this::mouseMove)
|
||||
|
||||
glfwSetWindowSizeCallback(window, this::onResize)
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
glfwTerminate()
|
||||
}
|
||||
|
||||
private fun onResize(window: Long, width: Int, height: Int) {
|
||||
if (window != this.window) {
|
||||
return
|
||||
}
|
||||
val previousSize = Vec2i(_size)
|
||||
_size = Vec2i(width, height)
|
||||
eventMaster.fireEvent(ResizeWindowEvent(previousSize = previousSize, size = _size))
|
||||
}
|
||||
|
||||
private fun mouseKeyInput(windowId: Long, button: Int, action: Int, modifierKey: Int) {
|
||||
keyInput(windowId, button, 0, action, modifierKey)
|
||||
}
|
||||
|
||||
private fun keyInput(window: Long, key: Int, char: Int, action: Int, modifierKey: Int) {
|
||||
if (window != this.window) {
|
||||
return
|
||||
}
|
||||
val keyCode = KeyCodes.KEY_CODE_GLFW_ID_MAP[key] ?: KeyCodes.KEY_UNKNOWN
|
||||
|
||||
val keyAction = when (action) {
|
||||
GLFW_PRESS -> KeyChangeTypes.PRESS
|
||||
GLFW_RELEASE -> KeyChangeTypes.RELEASE
|
||||
GLFW_REPEAT -> KeyChangeTypes.REPEAT
|
||||
else -> {
|
||||
Log.log(LogMessageType.RENDERING_GENERAL, LogLevels.WARN) { "Unknown glfw action $action" }
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
eventMaster.fireEvent(RawKeyInputEvent(keyCode = keyCode, keyChangeType = keyAction))
|
||||
}
|
||||
|
||||
private fun charInput(windowId: Long, char: Int) {
|
||||
if (windowId != window) {
|
||||
return
|
||||
}
|
||||
eventMaster.fireEvent(RawCharInputEvent(char = char))
|
||||
}
|
||||
|
||||
private fun mouseMove(windowId: Long, x: Double, y: Double) {
|
||||
if (windowId != window) {
|
||||
return
|
||||
}
|
||||
eventMaster.fireEvent(MouseMoveEvent(position = Vec2d(x, y)))
|
||||
}
|
||||
|
||||
companion object {
|
||||
val CursorModes.glfw: Int
|
||||
get() {
|
||||
return when (this) {
|
||||
CursorModes.NORMAL -> GLFW_CURSOR_NORMAL
|
||||
CursorModes.HIDDEN -> GLFW_CURSOR_HIDDEN
|
||||
CursorModes.DISABLED -> GLFW_CURSOR_DISABLED
|
||||
}
|
||||
}
|
||||
|
||||
val Boolean.glfw: Int
|
||||
get() {
|
||||
return when (this) {
|
||||
true -> GLFW_TRUE
|
||||
false -> GLFW_FALSE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.window
|
||||
|
||||
enum class KeyChangeTypes {
|
||||
PRESS,
|
||||
RELEASE,
|
||||
REPEAT,
|
||||
;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.modding.event
|
||||
|
||||
import de.bixilon.minosoft.modding.event.events.Event
|
||||
|
||||
interface EventMaster {
|
||||
|
||||
fun fireEvent(event: Event): Boolean
|
||||
|
||||
fun registerEvent(method: EventInvoker)
|
||||
|
||||
fun registerEvents(vararg method: EventInvoker)
|
||||
}
|
@ -15,8 +15,9 @@ package de.bixilon.minosoft.protocol.network.connection
|
||||
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.modding.event.EventInvoker
|
||||
import de.bixilon.minosoft.modding.event.EventMaster
|
||||
import de.bixilon.minosoft.modding.event.events.CancelableEvent
|
||||
import de.bixilon.minosoft.modding.event.events.ConnectionEvent
|
||||
import de.bixilon.minosoft.modding.event.events.Event
|
||||
import de.bixilon.minosoft.modding.event.events.PacketSendEvent
|
||||
import de.bixilon.minosoft.protocol.network.Network
|
||||
import de.bixilon.minosoft.protocol.packets.c2s.C2SPacket
|
||||
@ -27,7 +28,7 @@ import de.bixilon.minosoft.protocol.protocol.PacketTypes.S2C
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedListOf
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedList
|
||||
|
||||
abstract class Connection {
|
||||
abstract class Connection : EventMaster {
|
||||
val network = Network.getNetworkInstance(this)
|
||||
protected val eventListeners: MutableList<EventInvoker> = synchronizedListOf()
|
||||
val connectionId = lastConnectionId++
|
||||
@ -47,24 +48,24 @@ abstract class Connection {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param connectionEvent The event to fire
|
||||
* @param event The event to fire
|
||||
* @return if the event has been cancelled or not
|
||||
*/
|
||||
fun fireEvent(connectionEvent: ConnectionEvent): Boolean {
|
||||
override fun fireEvent(event: Event): Boolean {
|
||||
for (eventManager in Minosoft.EVENT_MANAGERS) {
|
||||
for (eventListener in eventManager.globalEventListeners) {
|
||||
eventListener(connectionEvent)
|
||||
eventListener(event)
|
||||
}
|
||||
}
|
||||
|
||||
for (eventInvoker in eventListeners.toSynchronizedList()) {
|
||||
if (!eventInvoker.eventType.isAssignableFrom(connectionEvent::class.java)) {
|
||||
if (!eventInvoker.eventType.isAssignableFrom(event::class.java)) {
|
||||
continue
|
||||
}
|
||||
eventInvoker(connectionEvent)
|
||||
eventInvoker(event)
|
||||
}
|
||||
if (connectionEvent is CancelableEvent) {
|
||||
return connectionEvent.isCancelled
|
||||
if (event is CancelableEvent) {
|
||||
return event.isCancelled
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -84,11 +85,11 @@ abstract class Connection {
|
||||
eventListeners.remove(method)
|
||||
}
|
||||
|
||||
open fun registerEvent(method: EventInvoker) {
|
||||
override fun registerEvent(method: EventInvoker) {
|
||||
eventListeners.add(method)
|
||||
}
|
||||
|
||||
open fun registerEvents(vararg method: EventInvoker) {
|
||||
override fun registerEvents(vararg method: EventInvoker) {
|
||||
eventListeners.addAll(method)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user