From bb37f2aed7ae5855a6fd1cae4628b9de2c7e3ddc Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Sun, 9 Apr 2017 22:22:29 +0900 Subject: [PATCH] UIs will draw on "backing" framebuffer where skybox is --- src/net/torvald/terrarum/StateInGame.kt | 51 +++++++++++-------- src/net/torvald/terrarum/StateUITest.kt | 6 +++ .../terrarum/ui/BasicDebugInfoWindow.kt | 2 +- src/net/torvald/terrarum/ui/ConsoleWindow.kt | 2 +- src/net/torvald/terrarum/ui/UIHandler.kt | 25 +++------ src/net/torvald/terrarum/ui/UIInventory.kt | 11 ++-- src/net/torvald/terrarum/ui/UIPieMenu.kt | 2 +- src/net/torvald/terrarum/ui/UIVitalMetre.kt | 44 ++++++++++++---- 8 files changed, 88 insertions(+), 55 deletions(-) diff --git a/src/net/torvald/terrarum/StateInGame.kt b/src/net/torvald/terrarum/StateInGame.kt index 79ddc34ba..2ed6b2d98 100644 --- a/src/net/torvald/terrarum/StateInGame.kt +++ b/src/net/torvald/terrarum/StateInGame.kt @@ -80,8 +80,8 @@ class StateInGame : BasicGameState() { val worldDrawFrameBuffer = Image(Terrarum.WIDTH.div(ZOOM_MIN).ceilInt(), Terrarum.HEIGHT.div(ZOOM_MIN).ceilInt()) val worldG = worldDrawFrameBuffer.graphics - val uisDrawFrameBuffer = Image(Terrarum.WIDTH, Terrarum.HEIGHT) - val uiG = uisDrawFrameBuffer.graphics + val backDrawFrameBuffer = Image(Terrarum.WIDTH, Terrarum.HEIGHT) + val backG = backDrawFrameBuffer.graphics //private lateinit var shader12BitCol: Shader // grab LibGDX if you want some shader //private lateinit var shaderBlur: Shader @@ -198,11 +198,11 @@ class StateInGame : BasicGameState() { // vital metre // fill in getter functions by // (uiAliases[UI_QUICK_BAR]!!.UI as UIVitalMetre).vitalGetterMax = { some_function } - uiAliases[UI_VITAL1] = UIHandler(UIVitalMetre(player, { 80f }, { 100f }, Color.red, 0)) + uiAliases[UI_VITAL1] = UIHandler(UIVitalMetre(player, { 80f }, { 100f }, Color.red, 0), customPositioning = true) uiAliases[UI_VITAL1]!!.setAsAlwaysVisible() - uiAliases[UI_VITAL2] = UIHandler(UIVitalMetre(player, { 73f }, { 100f }, Color(0x00dfff), 1)) + uiAliases[UI_VITAL2] = UIHandler(UIVitalMetre(player, { 73f }, { 100f }, Color(0x00dfff), 1), customPositioning = true) uiAliases[UI_VITAL2]!!.setAsAlwaysVisible() - uiAliases[UI_VITAL3] = UIHandler(UIVitalMetre(player, { 32f }, { 100f }, Color(0xffcc00), 2)) + uiAliases[UI_VITAL3] = UIHandler(UIVitalMetre(player, { 32f }, { 100f }, Color(0xffcc00), 2), customPositioning = true) uiAliases[UI_VITAL3]!!.setAsAlwaysVisible() @@ -357,17 +357,16 @@ class StateInGame : BasicGameState() { // clean the shit beforehand worldG.clear() - uiG.clear() + backG.clear() blendNormal() - drawSkybox(gwin) // drawing to gwin so that any lights from lamp wont "leak" to the skybox + drawSkybox(backG) // drawing to gwin so that any lights from lamp wont "leak" to the skybox // e.g. Bright blue light on sunset - // make camara work // - // compensate for zoom. UIs must be treated specially! (see UIHandler) + // make camara work worldG.translate(-MapCamera.x.toFloat(), -MapCamera.y.toFloat()) @@ -472,21 +471,31 @@ class StateInGame : BasicGameState() { WorldSimulator.drawFluidMapDebug(worldG) - ////////////// - // draw UIs // - ////////////// - uiContainer.forEach { if (it != consoleHandler) it.render(gc, sbg, uiG) } - debugWindow.render(gc, sbg, uiG) + + + ///////////////// + // GUI Predraw // + ///////////////// + worldG.flush() + backG.drawImage(worldDrawFrameBuffer.getScaledCopy(screenZoom), 0f, 0f) + backG.flush() + + + ///////////////////// + // draw UIs ONLY! // + ///////////////////// + uiContainer.forEach { if (it != consoleHandler) it.render(gc, sbg, backG) } + debugWindow.render(gc, sbg, backG) // make sure console draws on top of other UIs - consoleHandler.render(gc, sbg, uiG) - notifier.render(gc, sbg, uiG) + consoleHandler.render(gc, sbg, backG) + notifier.render(gc, sbg, backG) - ///////////////// - // draw layers // - ///////////////// - gwin.drawImage(worldDrawFrameBuffer.getScaledCopy(screenZoom), 0f, 0f) - gwin.drawImage(uisDrawFrameBuffer, 0f, 0f) + ////////////////// + // GUI Postdraw // + ////////////////// + backG.flush() + gwin.drawImage(backDrawFrameBuffer, 0f, 0f) // centre marker diff --git a/src/net/torvald/terrarum/StateUITest.kt b/src/net/torvald/terrarum/StateUITest.kt index d959c2fe2..56251da94 100644 --- a/src/net/torvald/terrarum/StateUITest.kt +++ b/src/net/torvald/terrarum/StateUITest.kt @@ -88,6 +88,12 @@ class StateUITest : BasicGameState() { override fun getID() = Terrarum.STATE_ID_TEST_UI1 override fun render(container: GameContainer, game: StateBasedGame, g: Graphics) { + blendNormal() + g.color = Color.green + g.fillRect(0f, 0f, 2048f, 2048f) + + + ui.render(container, game, g) } } diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index b2496e468..09a186a45 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -193,7 +193,7 @@ class BasicDebugInfoWindow : UICanvas { val histogramH = 200 private fun drawHistogram(g: Graphics, histogram: LightmapRenderer.Histogram, x: Int, y: Int) { - val uiColour = Color(0xAA000000.toInt()) + val uiColour = Color(0x80000000.toInt()) val barR = Color(0xDD0000) val barG = Color(0x00DD00) val barB = Color(0x0000DD) diff --git a/src/net/torvald/terrarum/ui/ConsoleWindow.kt b/src/net/torvald/terrarum/ui/ConsoleWindow.kt index bc73e1e90..07c1ed304 100644 --- a/src/net/torvald/terrarum/ui/ConsoleWindow.kt +++ b/src/net/torvald/terrarum/ui/ConsoleWindow.kt @@ -16,7 +16,7 @@ import org.newdawn.slick.Input */ class ConsoleWindow : UICanvas, KeyboardControlled { - internal var UIColour = Color(0xCC000000.toInt()) + internal var UIColour = Color(0x80404080.toInt()) private var inputCursorPos: Int = 0 private val MESSAGES_MAX = 5000 diff --git a/src/net/torvald/terrarum/ui/UIHandler.kt b/src/net/torvald/terrarum/ui/UIHandler.kt index d87612f29..61aa1b7ef 100644 --- a/src/net/torvald/terrarum/ui/UIHandler.kt +++ b/src/net/torvald/terrarum/ui/UIHandler.kt @@ -18,18 +18,17 @@ import org.newdawn.slick.state.StateBasedGame * Created by minjaesong on 15-12-31. */ class UIHandler(val UI: UICanvas, - val toggleKey: Int? = null, val toggleButton: Int? = null + val toggleKey: Int? = null, val toggleButton: Int? = null, + // UI positions itself? (you must g.flush() yourself after the g.translate(Int, Int)) + var customPositioning: Boolean = false ) { - // X/Y Position to the game window. + // X/Y Position relative to the game window. var posX: Int = 0 var posY: Int = 0 private var alwaysVisible = false - private val UIGraphicInstance: Graphics - private val UIDrawnCanvas: Image - var isOpening = false var isClosing = false var isOpened = false // fully opened @@ -56,11 +55,6 @@ class UIHandler(val UI: UICanvas, init { UI.handler = this - - println("[UIHandler] Creating framebuffer for UI '${UI.javaClass.simpleName}'") - - UIDrawnCanvas = Image(UI.width, UI.height) - UIGraphicInstance = UIDrawnCanvas.graphics } @@ -123,14 +117,11 @@ class UIHandler(val UI: UICanvas, fun render(gc: GameContainer, sbg: StateBasedGame, ingameGraphics: Graphics) { if (isVisible || alwaysVisible) { - UIGraphicInstance.clear() - UIGraphicInstance.font = Terrarum.fontGame + ingameGraphics.font = Terrarum.fontGame // default font. Re-assign in the UI to change - UI.render(gc, UIGraphicInstance) - - ingameGraphics.drawImage( - UIDrawnCanvas, posX.toFloat(), posY.toFloat(), Color(1f, 1f, 1f, opacity) - ) + if (!customPositioning) ingameGraphics.translate(posX.toFloat(), posY.toFloat()) + UI.render(gc, ingameGraphics) + ingameGraphics.flush() } } diff --git a/src/net/torvald/terrarum/ui/UIInventory.kt b/src/net/torvald/terrarum/ui/UIInventory.kt index c9aed2e25..9da1ecfc7 100644 --- a/src/net/torvald/terrarum/ui/UIInventory.kt +++ b/src/net/torvald/terrarum/ui/UIInventory.kt @@ -28,7 +28,7 @@ class UIInventory( val catButtonsToCatIdent = HashMap() - val backgroundColour = Color(0x1c1c1c) + val backgroundColour = Color(0xA0282828.toInt()) init { catButtonsToCatIdent.put("GAME_INVENTORY_WEAPONS", InventoryItem.Category.WEAPON) @@ -73,9 +73,10 @@ class UIInventory( defaultSelection = 0, iconSpriteSheet = SpriteSheet("./assets/graphics/gui/inventory/category.tga", 20, 20), iconSpriteSheetIndices = intArrayOf(9,0,1,2,3,4,5,6,7,8), - highlightBackCol = backgroundColour screen Color(0x0c0c0c), - highlightBackBlendMode = BlendMode.NORMAL, + highlightBackCol = Color(0x0c0c0c), + highlightBackBlendMode = BlendMode.SCREEN, backgroundCol = Color(0x383838), + backgroundBlendMode = BlendMode.MULTIPLY, kinematic = true ) @@ -93,8 +94,6 @@ class UIInventory( mouseoverBackCol = Color(0x282828), mouseoverBackBlendMode = BlendMode.SCREEN, drawBackOnNull = false - //backCol = Color(0x101010), - //backBlendMode = BlendMode.SCREEN ) }) val itemsScrollOffset = 0 @@ -175,6 +174,8 @@ class UIInventory( } override fun render(gc: GameContainer, g: Graphics) { + //blendMul() + blendNormal() g.color = backgroundColour g.fillRect(0f, 0f, width.toFloat(), height.toFloat()) diff --git a/src/net/torvald/terrarum/ui/UIPieMenu.kt b/src/net/torvald/terrarum/ui/UIPieMenu.kt index 8f37cb880..54fdb2d82 100644 --- a/src/net/torvald/terrarum/ui/UIPieMenu.kt +++ b/src/net/torvald/terrarum/ui/UIPieMenu.kt @@ -48,7 +48,7 @@ class UIPieMenu : UICanvas { for (i in 0..slotCount - 1) { // set position val angle = Math.PI * 2.0 * (i.toDouble() / slotCount) + Math.PI // 180 deg monitor-wise - val slotCentrePoint = Vector2(0.0, slotDistanceFromCentre.toDouble()).setDirection(angle) + centrePoint + val slotCentrePoint = Vector2(0.0, slotDistanceFromCentre).setDirection(angle) + centrePoint // draw cells val color = if (i == selection) diff --git a/src/net/torvald/terrarum/ui/UIVitalMetre.kt b/src/net/torvald/terrarum/ui/UIVitalMetre.kt index 1ab0e66db..e4a6034ba 100644 --- a/src/net/torvald/terrarum/ui/UIVitalMetre.kt +++ b/src/net/torvald/terrarum/ui/UIVitalMetre.kt @@ -5,6 +5,7 @@ import net.torvald.terrarum.Terrarum import net.torvald.terrarum.gameactors.ActorHumanoid import net.torvald.terrarum.gameactors.floorInt import net.torvald.terrarum.gameactors.roundInt +import net.torvald.terrarum.mapdrawer.MapCamera import org.newdawn.slick.Color import org.newdawn.slick.GameContainer import org.newdawn.slick.Graphics @@ -27,10 +28,17 @@ class UIVitalMetre( override var width: Int = 80 + 2 * margin; set(value) { throw Error("operation not permitted") } override var height: Int; get() = player?.baseHitboxH ?: 0 * 3 + margin; set(value) { throw Error("operation not permitted") } override var handler: UIHandler? = null + set(value) { + // override customPositioning to be true + if (value != null) { + value.customPositioning = true + } + field = value + } override var openCloseTime: Int = 50 - private val relativePX = width / 2f - private val relativePY: Float; get() = (player?.baseHitboxH ?: 0) * 1.5f + //private val relativePX = width / 2f + private val offsetY: Float; get() = (player?.baseHitboxH ?: 0) * 1.5f private val circleRadius: Float; get() = (player?.baseHitboxH ?: 0) * 3f private val theta = 33f @@ -41,21 +49,35 @@ class UIVitalMetre( override fun update(gc: GameContainer, delta: Int) { handler!!.setPosition( - (Terrarum.HALFW - relativePX).roundInt(), - (Terrarum.HALFH - relativePY).floorInt() + Terrarum.HALFW, + Terrarum.HALFH ) + + handler!!.customPositioning = true } + /** + * g must be same as World Graphics! + */ override fun render(gc: GameContainer, g: Graphics) { - if (vitalGetterVal() != null && vitalGetterMax() != null) { + if (vitalGetterVal() != null && vitalGetterMax() != null && player != null) { + + // FIXME does not work well with screen zoom, because of my custom g.translate + + g.translate( + -MapCamera.x + player!!.centrePosPoint.x.toFloat(), + -MapCamera.y + player!!.centrePosPoint.y.toFloat() + ) + + g.lineWidth = 2f // background g.color = backColor g.drawArc( - relativePX - circleRadius - order * gap, -circleRadius - order * gap, + -circleRadius - order * gap - offsetY, circleRadius * 2f + order * gap * 2, circleRadius * 2f + order * gap * 2, 90f - halfTheta, @@ -64,13 +86,17 @@ class UIVitalMetre( g.color = color g.drawArc( - relativePX - circleRadius - order * gap, -circleRadius - order * gap, + -circleRadius - order * gap - offsetY, circleRadius * 2f + order * gap * 2, circleRadius * 2f + order * gap * 2, 90f + halfTheta - theta * (vitalGetterVal()!! / vitalGetterMax()!!), 90f + halfTheta ) + + + + g.flush() } } @@ -96,10 +122,10 @@ class UIVitalMetre( /* -X-------------+ (84) ++-------------+ (84) | | | | -| @ | +| X | | @ | |, ,| | ''-------'' |