From a3ef1b435dd9a3365e468740ada3b09ea2ba9a2a Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 16 Feb 2019 17:11:36 +0900 Subject: [PATCH] buildingmaker penmenu; resolving mouse click clash between world and UIs --- .../graphics/blocks/block_markings_common.tga | 4 +- src/net/torvald/terrarum/AppLoader.java | 10 + src/net/torvald/terrarum/PostProcessor.kt | 9 + src/net/torvald/terrarum/Terrarum.kt | 3 + .../terrarum/blockproperties/BlockCodex.kt | 4 +- .../terrarum/modulebasegame/BuildingMaker.kt | 111 ++++++- .../terrarum/modulebasegame/EntryPoint.kt | 4 + .../terrarum/modulebasegame/IngameRenderer.kt | 2 + .../UIBuildingMakerBlockChooser.kt | 30 +- .../modulebasegame/UIBuildingMakerPenMenu.kt | 102 ++++++ .../modulebasegame/gameactors/DroppedItem.kt | 3 +- .../terrarum/worlddrawer/BlocksDrawerNew.kt | 4 + .../worlddrawer/LightmapRendererNew.kt | 306 ++++++------------ work_files/UI/building_maker_UI.psd | 4 +- 14 files changed, 354 insertions(+), 242 deletions(-) create mode 100644 src/net/torvald/terrarum/modulebasegame/UIBuildingMakerPenMenu.kt diff --git a/assets/graphics/blocks/block_markings_common.tga b/assets/graphics/blocks/block_markings_common.tga index 454ddbc26..6e7094947 100644 --- a/assets/graphics/blocks/block_markings_common.tga +++ b/assets/graphics/blocks/block_markings_common.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f7b380c4b03fdf806ca0a72b45de449a3555f792384d3ef8222e60c8dd7c9de1 -size 6188 +oid sha256:8744dad1ac3977e312f38f99aa005ef68c2192ebf2c927b740536fc71912e6a4 +size 16428 diff --git a/src/net/torvald/terrarum/AppLoader.java b/src/net/torvald/terrarum/AppLoader.java index de396c8cc..f0e5b4ba2 100644 --- a/src/net/torvald/terrarum/AppLoader.java +++ b/src/net/torvald/terrarum/AppLoader.java @@ -269,6 +269,7 @@ public class AppLoader implements ApplicationListener { public static int screenH = 0; public static Texture textureWhiteSquare; + public static Texture textureWhiteCircle; private void initViewPort(int width, int height) { // Set Y to point downwards @@ -506,19 +507,26 @@ public class AppLoader implements ApplicationListener { } IngameRenderer.INSTANCE.dispose(); + PostProcessor.INSTANCE.dispose(); Terrarum.INSTANCE.dispose(); shaderBayerSkyboxFill.dispose(); shaderHicolour.dispose(); + shaderPassthru.dispose(); shaderColLUT.dispose(); assetManager.dispose(); fullscreenQuad.dispose(); + logoBatch.dispose(); fontGame.dispose(); fontSmallNumbers.dispose(); + textureWhiteSquare.dispose(); + textureWhiteCircle.dispose(); + logo.getTexture().dispose(); + ModMgr.INSTANCE.disposeMods(); // delete temp files @@ -562,6 +570,8 @@ public class AppLoader implements ApplicationListener { textureWhiteSquare = new Texture(Gdx.files.internal("assets/graphics/ortho_line_tex_2px.tga")); textureWhiteSquare.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest); + textureWhiteCircle = new Texture(Gdx.files.internal("assets/graphics/circle_512.tga")); + TextureRegionPack.Companion.setGlobalFlipY(true); fontGame = new GameFontBase("assets/graphics/fonts/terrarum-sans-bitmap", false, true, Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest, false, 256, false diff --git a/src/net/torvald/terrarum/PostProcessor.kt b/src/net/torvald/terrarum/PostProcessor.kt index 424f23295..556a77da4 100644 --- a/src/net/torvald/terrarum/PostProcessor.kt +++ b/src/net/torvald/terrarum/PostProcessor.kt @@ -37,6 +37,15 @@ object PostProcessor { private val debugUI = BasicDebugInfoWindow() + fun dispose() { + batch.dispose() + shapeRenderer.dispose() + try { + lutTex.dispose() + } + catch (e: UninitializedPropertyAccessException) { } + } + fun draw(projMat: Matrix4, fbo: FrameBuffer) { // init diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 3b4223ad8..219812087 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -509,6 +509,9 @@ fun Float.round(): Float { fun SpriteBatch.fillRect(x: Float, y: Float, w: Float, h: Float) { this.draw(AppLoader.textureWhiteSquare, x, y, w, h) } +fun SpriteBatch.fillCircle(x: Float, y: Float, w: Float, h: Float) { + this.draw(AppLoader.textureWhiteCircle, x, y, w, h) +} fun SpriteBatch.drawStraightLine(x: Float, y: Float, otherEnd: Float, thickness: Float, isVertical: Boolean) { if (!isVertical) this.fillRect(x, y, otherEnd - x, thickness) diff --git a/src/net/torvald/terrarum/blockproperties/BlockCodex.kt b/src/net/torvald/terrarum/blockproperties/BlockCodex.kt index 5f16215d8..c83f71830 100644 --- a/src/net/torvald/terrarum/blockproperties/BlockCodex.kt +++ b/src/net/torvald/terrarum/blockproperties/BlockCodex.kt @@ -18,12 +18,12 @@ object BlockCodex { private var blockProps: Array - const val TILE_UNIQUE_MAX = MapLayer.RANGE * PairedMapLayer.RANGE + const val MAX_TERRAIN_TILES = MapLayer.RANGE * PairedMapLayer.RANGE private val nullProp = BlockProp() init { - blockProps = Array(TILE_UNIQUE_MAX * 2, { BlockProp() }) + blockProps = Array(MAX_TERRAIN_TILES * 2, { BlockProp() }) } /** diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index e2f829921..0f75669a2 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -6,7 +6,9 @@ import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import net.torvald.terrarum.* import net.torvald.terrarum.blockproperties.Block +import net.torvald.terrarum.blockproperties.BlockCodex import net.torvald.terrarum.gameactors.* +import net.torvald.terrarum.itemproperties.ItemID import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension import net.torvald.terrarum.modulebasegame.gameworld.WorldTime @@ -33,12 +35,17 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { - Import… - Save terrain… - Load terrain… + - - Exit to Title : net.torvald.terrarum.modulebasegame.YamlCommandExit - Tool - Pencil : net.torvald.terrarum.modulebasegame.YamlCommandToolPencil - - Eyedropper - - Select mrq. : net.torvald.terrarum.modulebasegame.YamlCommandToolMarquee - - Move + - Eraser : net.torvald.terrarum.modulebasegame.YamlCommandToolPencilErase + - Wall Hammer : net.torvald.terrarum.modulebasegame.YamlCommandToolPencilEraseWall + - Eyedropper : net.torvald.terrarum.modulebasegame.YamlCommandToolEyedropper + - Add Selection : net.torvald.terrarum.modulebasegame.YamlCommandToolMarquee + - Remove Sel. : net.torvald.terrarum.modulebasegame.YamlCommandToolMarqueeErase + - Clear Sel. + - Move Selected - Undo - Redo - Time @@ -84,12 +91,15 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { val notifier = Notification() val uiPaletteSelector = UIPaletteSelector(this) val uiPalette = UIBuildingMakerBlockChooser(this) + val uiPenMenu = UIBuildingMakerPenMenu(this) val uiContainer = ArrayList() var currentPenMode = PENMODE_PENCIL + var currentPenTarget = PENTARGET_TERRAIN + val selection = ArrayList() val blockPointingCursor = object : ActorWithBody(Actor.RenderOrder.OVERLAY) { @@ -130,11 +140,20 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { companion object { const val PENMODE_PENCIL = 0 - const val PENMODE_MARQUEE = 1 + const val PENMODE_PENCIL_ERASE = 1 + const val PENMODE_MARQUEE = 2 + const val PENMODE_MARQUEE_ERASE = 3 + const val PENMODE_EYEDROPPER = 4 + + const val PENTARGET_TERRAIN = 1 + const val PENTARGET_WALL = 2 val toolCursorColour = arrayOf( Color.YELLOW, - Color.MAGENTA + Color.YELLOW, + Color.MAGENTA, + Color.MAGENTA, + Color.WHITE ) } @@ -150,6 +169,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { uiContainer.add(uiPaletteSelector) uiContainer.add(notifier) uiContainer.add(uiPalette) + uiContainer.add(uiPenMenu) @@ -168,7 +188,6 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { uiPalette.setPosition(200, 100) - uiPalette.isVisible = true // TEST CODE should not be visible LightmapRenderer.fireRecalculateEvent() @@ -206,30 +225,47 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { } - private fun updateGame(delta: Float) { - var mouseOnUI = false + private var mouseOnUI = false + internal var tappedOnUI = false // when true, even if the UI is closed, pen won't work unless your pen is lifted + // must be set to TRUE by UIs + private fun updateGame(delta: Float) { WeatherMixer.update(delta, actorNowPlaying, gameWorld) blockPointingCursor.update(delta) actorNowPlaying?.update(delta) + var overwriteMouseOnUI = false uiContainer.forEach { it.update(delta) if (it.isVisible && it.mouseUp) { - mouseOnUI = true + overwriteMouseOnUI = true } } + mouseOnUI = (overwriteMouseOnUI || uiPenMenu.isVisible) + + WorldCamera.update(world, actorNowPlaying) // make pen work HERE - if (Gdx.input.isTouched && !mouseOnUI) { + // when LEFT mouse is down + if (!tappedOnUI && Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary")) && !mouseOnUI) { makePenWork(Terrarum.mouseTileX, Terrarum.mouseTileY) // TODO drag support using bresenham's algo // for some reason it just doesn't work... + } + else if (!uiPenMenu.isVisible && Gdx.input.isButtonPressed(AppLoader.getConfigInt("mousesecondary"))) { + // open pen menu + // position the menu to where the cursor is + uiPenMenu.posX = Terrarum.mouseScreenX - uiPenMenu.width / 2 + uiPenMenu.posY = Terrarum.mouseScreenY - uiPenMenu.height / 2 + uiPenMenu.posX = uiPenMenu.posX.coerceIn(0, Terrarum.WIDTH - uiPenMenu.width) + uiPenMenu.posY = uiPenMenu.posY.coerceIn(0, Terrarum.HEIGHT - uiPenMenu.height) + // actually open + uiPenMenu.setAsOpen() } } @@ -246,18 +282,37 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { println("[BuildingMaker] Resize event") } + fun setPencilColour(itemID: ItemID) { + uiPaletteSelector.fore = itemID + } + override fun dispose() { blockPointingCursor.dispose() } - private fun makePenWork(worldTileX: Int, worldTileY: Int) { + private fun makePenWork(x: Int, y: Int) { val world = gameWorld val palSelection = uiPaletteSelector.fore when (currentPenMode) { // test paint terrain layer PENMODE_PENCIL -> { - world.setTileTerrain(worldTileX, worldTileY, palSelection) + if (palSelection < BlockCodex.MAX_TERRAIN_TILES) + world.setTileTerrain(x, y, palSelection) + else if (palSelection < 2 * BlockCodex.MAX_TERRAIN_TILES) + world.setTileWall(x, y, palSelection - BlockCodex.MAX_TERRAIN_TILES) + } + PENMODE_PENCIL_ERASE -> { + if (currentPenTarget and PENTARGET_WALL != 0) + world.setTileWall(x, y, Block.AIR) + else + world.setTileTerrain(x, y, Block.AIR) + } + PENMODE_EYEDROPPER -> { + uiPaletteSelector.fore = if (world.getTileFromTerrain(x, y) == Block.AIR) + world.getTileFromWall(x, y)!! + BlockCodex.MAX_TERRAIN_TILES + else + world.getTileFromTerrain(x, y)!! } } } @@ -266,6 +321,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { class BuildingMakerController(val screen: BuildingMaker) : InputAdapter() { override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { screen.uiContainer.forEach { it.touchUp(screenX, screenY, pointer, button) } + screen.tappedOnUI = false return true } @@ -289,7 +345,6 @@ class BuildingMakerController(val screen: BuildingMaker) : InputAdapter() { return true } - // let left mouse button to paint, because that's how graphic tablets work override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean { screen.uiContainer.forEach { it.touchDragged(screenX, screenY, pointer) } return true @@ -368,6 +423,28 @@ class YamlCommandSetTimeNight : YamlInvokable { class YamlCommandToolPencil : YamlInvokable { override fun invoke(args: Array) { (args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_PENCIL + (args[0] as BuildingMaker).currentPenTarget = BuildingMaker.PENTARGET_TERRAIN + } +} + +class YamlCommandToolPencilErase : YamlInvokable { + override fun invoke(args: Array) { + (args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_PENCIL_ERASE + (args[0] as BuildingMaker).currentPenTarget = BuildingMaker.PENTARGET_TERRAIN + } +} + +class YamlCommandToolPencilEraseWall : YamlInvokable { + override fun invoke(args: Array) { + (args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_PENCIL_ERASE + (args[0] as BuildingMaker).currentPenTarget = BuildingMaker.PENTARGET_WALL + } +} + +class YamlCommandToolEyedropper : YamlInvokable { + override fun invoke(args: Array) { + (args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_EYEDROPPER + (args[0] as BuildingMaker).currentPenTarget = BuildingMaker.PENTARGET_TERRAIN } } @@ -375,4 +452,10 @@ class YamlCommandToolMarquee : YamlInvokable { override fun invoke(args: Array) { (args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_MARQUEE } -} \ No newline at end of file +} + +class YamlCommandToolMarqueeErase : YamlInvokable { + override fun invoke(args: Array) { + (args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_MARQUEE_ERASE + } +} diff --git a/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt b/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt index 241f423e0..9cf0e2d35 100644 --- a/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt +++ b/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt @@ -11,6 +11,7 @@ import net.torvald.terrarum.gameactors.ActorWBMovable import net.torvald.terrarum.itemproperties.GameItem import net.torvald.terrarum.itemproperties.ItemCodex import net.torvald.terrarum.itemproperties.Material +import net.torvald.terrarum.modulebasegame.imagefont.WatchFont /** * The entry point for the module "Basegame" @@ -103,4 +104,7 @@ class EntryPoint : ModuleEntryPoint() { println("Welcome back!") } + override fun dispose() { + WatchFont.dispose() + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index 20381d188..d882cf66b 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -588,6 +588,8 @@ object IngameRenderer { LightmapRenderer.dispose() BlocksDrawer.dispose() WeatherMixer.dispose() + + batch.dispose() } private fun worldCamToRenderPos(): Pair { diff --git a/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerBlockChooser.kt b/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerBlockChooser.kt index 4926a9ab5..8e4419e38 100644 --- a/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerBlockChooser.kt +++ b/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerBlockChooser.kt @@ -3,6 +3,8 @@ package net.torvald.terrarum.modulebasegame import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.terrarum.blendNormal +import net.torvald.terrarum.blendScreen import net.torvald.terrarum.fillRect import net.torvald.terrarum.itemproperties.ItemCodex import net.torvald.terrarum.ui.UICanvas @@ -21,7 +23,7 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() { const val TILESREGION_SIZE = 24 const val MENUBAR_SIZE = 80 - const val SCROLLBAR_SIZE = 16 + const val SCROLLBAR_SIZE = 24 const val WIDTH = TILES_X*TILESREGION_SIZE + SCROLLBAR_SIZE + MENUBAR_SIZE const val HEIGHT = TILES_Y*TILESREGION_SIZE @@ -60,14 +62,31 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() { palette.forEach { it.update(delta) } tabs.update(delta) closeButton.update(delta) + if (closeButton.mousePushed) { + parent.tappedOnUI = true + isVisible = false + } } + private val addCol = Color(0x242424ff) + private var scrollBarPos = 0 + private val scrollBarHeight = (HEIGHT - 16*14).toFloat() + private val scrollableArea = HEIGHT - scrollBarHeight + override fun renderUI(batch: SpriteBatch, camera: Camera) { palette.forEach { it.render(batch, camera) } // gaps between tabs and close button batch.color = DEFAULT_BACKGROUNDCOL batch.fillRect(0f, tabs.height.toFloat(), MENUBAR_SIZE.toFloat(), height.toFloat() - (tabs.height + closeButton.height)) + // scrollbar back + batch.fillRect(width - SCROLLBAR_SIZE.toFloat(), 0f, SCROLLBAR_SIZE.toFloat(), height.toFloat()) + blendScreen(batch) + batch.color = addCol + batch.fillRect(width - SCROLLBAR_SIZE.toFloat(), 0f, SCROLLBAR_SIZE.toFloat(), height.toFloat()) + // scrollbar + batch.fillRect(width - SCROLLBAR_SIZE.toFloat(), scrollBarPos.toFloat(), SCROLLBAR_SIZE.toFloat(), scrollBarHeight) + blendNormal(batch) // the actual buttons tabs.render(batch, camera) @@ -77,7 +96,6 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() { private var dragOriginX = 0 // relative mousepos private var dragOriginY = 0 // relative mousepos private var dragForReal = false - private var closeReady = false // so that it'll close when the mouse is DOWN then UP private fun mouseOnDragHandle() = relativeMouseX in 0 until MENUBAR_SIZE && relativeMouseY in tabs.height until height - closeButton.height @@ -96,22 +114,16 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() { dragOriginX = relativeMouseX dragOriginY = relativeMouseY dragForReal = true + parent.tappedOnUI = true } else { dragForReal = false } - closeReady = closeButton.mouseUp - return true } override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean { - if (closeReady && closeButton.mouseUp) { - closeButton.deselect() - this.isVisible = false - } - return true } diff --git a/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerPenMenu.kt b/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerPenMenu.kt new file mode 100644 index 000000000..ac9e6c2cc --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/UIBuildingMakerPenMenu.kt @@ -0,0 +1,102 @@ +package net.torvald.terrarum.modulebasegame + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.Input +import com.badlogic.gdx.graphics.Camera +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import net.torvald.terrarum.AppLoader +import net.torvald.terrarum.fillCircle +import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory +import net.torvald.terrarum.roundInt +import net.torvald.terrarum.sqr +import net.torvald.terrarum.ui.UICanvas +import org.dyn4j.geometry.Vector2 + +/** + * Created by minjaesong on 2019-02-16. + */ +class UIBuildingMakerPenMenu(val parent: BuildingMaker): UICanvas() { + + companion object { + const val SIZE = 400 + const val RADIUS = SIZE / 2.0 + const val RADIUSF = RADIUS.toFloat() + + const val BLOCKS_ROW_RADIUS = 150 + const val TOOLS_ROW_RADIUS = 72 + + const val BLOCK_BACK_SIZE = 72 + const val BLOCK_BACK_RADIUS = BLOCK_BACK_SIZE / 2f + + const val ICON_SIZE = 38 + const val ICON_HITBOX_SIZE = 52 + const val ICON_HITBOX_RADIUS = ICON_HITBOX_SIZE / 2f + + const val PALETTE_SIZE = 10 + } + + private val backCol = ItemSlotImageFactory.CELLCOLOUR_BLACK + private val blockCellCol = ItemSlotImageFactory.CELLCOLOUR_WHITE + /** Centre pos. */ + private val blockCellPos = Array(PALETTE_SIZE) { + val newvec = Vector2(0.0, 0.0 - BLOCKS_ROW_RADIUS) + newvec.rotate(Math.PI / 5.0 * it).plus(Vector2(RADIUS, RADIUS)) + } + + override var width = SIZE + override var height = SIZE + override var openCloseTime = 0f//UIQuickslotBar.COMMON_OPEN_CLOSE + + private var mouseVec = Vector2(0.0, 0.0) + + override fun updateUI(delta: Float) { + mouseVec.x = relativeMouseX.toDouble() + mouseVec.y = relativeMouseY.toDouble() + + if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) { + this.isVisible = false + parent.tappedOnUI = false + } + + // primary click + if (Gdx.input.isButtonPressed(AppLoader.getConfigInt("mouseprimary"))) { + // close by clicking close button or out-of-boud + if (mouseVec.distanceSquared(RADIUS, RADIUS) !in ICON_HITBOX_RADIUS.sqr()..RADIUSF.sqr()) { + this.isVisible = false + parent.tappedOnUI = true + } + } + } + + override fun renderUI(batch: SpriteBatch, camera: Camera) { + // draw back + batch.color = backCol + batch.fillCircle(0f, 0f, SIZE.toFloat(), SIZE.toFloat()) + + // draw fore + batch.color = blockCellCol + for (i in 0 until PALETTE_SIZE) { + val x = blockCellPos[i].x.roundInt().toFloat() - BLOCK_BACK_RADIUS + val y = blockCellPos[i].y.roundInt().toFloat() - BLOCK_BACK_RADIUS + batch.fillCircle(x, y, BLOCK_BACK_SIZE.toFloat(), BLOCK_BACK_SIZE.toFloat()) + } + + // draw close button + batch.fillCircle(RADIUSF - ICON_HITBOX_RADIUS, RADIUSF - ICON_HITBOX_RADIUS, ICON_HITBOX_SIZE.toFloat(), ICON_HITBOX_SIZE.toFloat()) + } + + override fun doOpening(delta: Float) { + } + + override fun doClosing(delta: Float) { + } + + override fun endOpening(delta: Float) { + } + + override fun endClosing(delta: Float) { + } + + override fun dispose() { + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt index d0181d645..aeae3d9bf 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/DroppedItem.kt @@ -5,7 +5,6 @@ import net.torvald.terrarum.itemproperties.GameItem import net.torvald.terrarum.itemproperties.ItemCodex import net.torvald.terrarum.blockproperties.BlockCodex import net.torvald.terrarum.gameactors.ActorWBMovable -import net.torvald.terrarum.gameworld.GameWorld /** * Created by minjaesong on 2016-03-15. @@ -18,7 +17,7 @@ open class DroppedItem(private val item: GameItem) : ActorWBMovable(RenderOrder. isVisible = true - avBaseMass = if (item.dynamicID < BlockCodex.TILE_UNIQUE_MAX) + avBaseMass = if (item.dynamicID < BlockCodex.MAX_TERRAIN_TILES) BlockCodex[item.dynamicID].density / 1000.0 else ItemCodex[item.dynamicID].mass diff --git a/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt b/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt index aa479cf89..3b38ce7f7 100644 --- a/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt +++ b/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt @@ -873,6 +873,10 @@ internal object BlocksDrawer { tilesWire.dispose() tileItemWall.dispose() tilesFluid.dispose() + tilesBuffer.dispose() + _tilesBufferAsTex.dispose() + tilesQuad.dispose() + shader.dispose() } fun getRenderStartX(): Int = WorldCamera.x / TILE_SIZE diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt index 762f939f8..2ea22b161 100644 --- a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt +++ b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt @@ -1,9 +1,11 @@ package net.torvald.terrarum.worlddrawer import com.badlogic.gdx.Gdx -import com.badlogic.gdx.graphics.* +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.GL20 +import com.badlogic.gdx.graphics.Pixmap +import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.SpriteBatch -import com.badlogic.gdx.graphics.glutils.FrameBuffer import com.badlogic.gdx.graphics.glutils.ShaderProgram import com.jme3.math.FastMath import net.torvald.terrarum.* @@ -38,7 +40,7 @@ object LightmapRenderer { private var world: GameWorld = GameWorld.makeNullWorld() private lateinit var lightCalcShader: ShaderProgram - private val SHADER_LIGHTING = AppLoader.getConfigBoolean("gpulightcalc") + //private val SHADER_LIGHTING = AppLoader.getConfigBoolean("gpulightcalc") /** do not call this yourself! Let your game renderer handle this! */ fun setWorld(world: GameWorld) { @@ -86,62 +88,8 @@ object LightmapRenderer { private val lightmap: Array = Array(LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT) { Color(0f,0f,0f,0f) } // Can't use framebuffer/pixmap -- this is a fvec4 array, whereas they are ivec4. private val lanternMap = HashMap((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4) - private lateinit var texturedLightMap: FrameBuffer - private lateinit var texturedLightMapOutput: Pixmap - private lateinit var texturedLightSources: Texture - private lateinit var texturedShadeSources: Texture - private lateinit var texturedLightSourcePixmap: Pixmap // used to turn tiles into texture - private lateinit var texturedShadeSourcePixmap: Pixmap // used to turn tiles into texture - private lateinit var texturedLightQuad: Mesh - private lateinit var texturedLightCamera: OrthographicCamera - private lateinit var texturedLightBatch: SpriteBatch - - private const val LIGHTMAP_UNIT = 0 - private const val SHADEMAP_UNIT = 1 - init { printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque") - - if (SHADER_LIGHTING) { - lightCalcShader = AppLoader.loadShader("assets/4096.vert", "assets/raytracelight.frag") - - texturedLightMap = FrameBuffer(Pixmap.Format.RGBA8888, LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT, false) - //texturedLightMap = Texture(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT, Pixmap.Format.RGBA8888) - //texturedLightMap.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - - texturedLightMapOutput = Pixmap(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT, Pixmap.Format.RGBA8888) - - texturedLightSources = Texture(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT, Pixmap.Format.RGBA8888) - texturedLightSources.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - - texturedShadeSources = Texture(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT, Pixmap.Format.RGBA8888) - texturedShadeSources.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) - - texturedLightSourcePixmap = Pixmap(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT, Pixmap.Format.RGBA8888) - texturedLightSourcePixmap.blending = Pixmap.Blending.None - texturedShadeSourcePixmap = Pixmap(LIGHTMAP_WIDTH, LIGHTMAP_HEIGHT, Pixmap.Format.RGBA8888) - texturedShadeSourcePixmap.blending = Pixmap.Blending.None - - texturedLightQuad = Mesh( - true, 4, 6, - VertexAttribute.Position(), - VertexAttribute.ColorUnpacked(), - VertexAttribute.TexCoords(0) - ) - texturedLightQuad.setVertices(floatArrayOf( // y-flipped quads! - 0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f, 0f, - LIGHTMAP_WIDTH.toFloat(), 0f, 0f, 1f, 1f, 1f, 1f, 1f, 0f, - LIGHTMAP_WIDTH.toFloat(), LIGHTMAP_HEIGHT.toFloat(), 0f, 1f, 1f, 1f, 1f, 1f, 1f, - 0f, LIGHTMAP_HEIGHT.toFloat(), 0f, 1f, 1f, 1f, 1f, 0f, 1f)) - texturedLightQuad.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0)) - - texturedLightCamera = OrthographicCamera(LIGHTMAP_WIDTH.toFloat(), LIGHTMAP_HEIGHT.toFloat()) - texturedLightCamera.setToOrtho(true) - texturedLightCamera.update() - - texturedLightBatch = SpriteBatch(8, lightCalcShader) - - } } private val AIR = Block.AIR @@ -260,139 +208,81 @@ object LightmapRenderer { buildLanternmap(actorContainers) } // usually takes 3000 ns - if (!SHADER_LIGHTING) { - /* - * Updating order: - * ,--------. ,--+-----. ,-----+--. ,--------. - - * |↘ | | | 3| |3 | | | ↙| ↕︎ overscan_open / overscan_opaque - * | ,-----+ | | 2 | | 2 | | +-----. | - depending on the noop_mask - * | |1 | | |1 | | 1| | | 1| | - * | | 2 | | `-----+ +-----' | | 2 | | - * | | 3| |↗ | | ↖| |3 | | - * `--+-----' `--------' `--------' `-----+--' - * round: 1 2 3 4 - * for all lightmap[y][x], run in this order: 2-3-4-1 - * If you run only 4 sets, orthogonal/diagonal artefacts are bound to occur, - */ + /* + * Updating order: + * ,--------. ,--+-----. ,-----+--. ,--------. - + * |↘ | | | 3| |3 | | | ↙| ↕︎ overscan_open / overscan_opaque + * | ,-----+ | | 2 | | 2 | | +-----. | - depending on the noop_mask + * | |1 | | |1 | | 1| | | 1| | + * | | 2 | | `-----+ +-----' | | 2 | | + * | | 3| |↗ | | ↖| |3 | | + * `--+-----' `--------' `--------' `-----+--' + * round: 1 2 3 4 + * for all lightmap[y][x], run in this order: 2-3-4-1 + * If you run only 4 sets, orthogonal/diagonal artefacts are bound to occur, + */ - // set sunlight - sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT) + // set sunlight + sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT) - // set no-op mask from solidity of the block - AppLoader.measureDebugTime("Renderer.LightNoOpMask") { - noopMask.clear() - buildNoopMask() - } + // set no-op mask from solidity of the block + AppLoader.measureDebugTime("Renderer.LightNoOpMask") { + noopMask.clear() + buildNoopMask() + } - // wipe out lightmap - AppLoader.measureDebugTime("Renderer.Light0") { - for (k in 0 until lightmap.size) lightmap[k] = colourNull - // when disabled, light will "decay out" instead of "instantly out", which can have a cool effect - // but the performance boost is measly 0.1 ms on 6700K - } - // O((5*9)n) == O(n) where n is a size of the map. - // Because of inevitable overlaps on the area, it only works with MAX blend + // wipe out lightmap + AppLoader.measureDebugTime("Renderer.Light0") { + for (k in 0 until lightmap.size) lightmap[k] = colourNull + // when disabled, light will "decay out" instead of "instantly out", which can have a cool effect + // but the performance boost is measly 0.1 ms on 6700K + } + // O((5*9)n) == O(n) where n is a size of the map. + // Because of inevitable overlaps on the area, it only works with MAX blend - // each usually takes 8 000 000..12 000 000 miliseconds total when not threaded + // each usually takes 8 000 000..12 000 000 miliseconds total when not threaded - if (!AppLoader.getConfigBoolean("multithreadedlight")) { + if (!AppLoader.getConfigBoolean("multithreadedlight")) { - // The skipping is dependent on how you get ambient light, - // in this case we have 'spillage' due to the fact calculate() samples 3x3 area. + // The skipping is dependent on how you get ambient light, + // in this case we have 'spillage' due to the fact calculate() samples 3x3 area. - AppLoader.measureDebugTime("Renderer.LightTotal") { - // Round 2 - for (y in for_y_end + overscan_open downTo for_y_start) { - for (x in for_x_start - overscan_open..for_x_end) { - calculateAndAssign(lightmap, x, y) - } + AppLoader.measureDebugTime("Renderer.LightTotal") { + // Round 2 + for (y in for_y_end + overscan_open downTo for_y_start) { + for (x in for_x_start - overscan_open..for_x_end) { + calculateAndAssign(lightmap, x, y) } - // Round 3 - for (y in for_y_end + overscan_open downTo for_y_start) { - for (x in for_x_end + overscan_open downTo for_x_start) { - calculateAndAssign(lightmap, x, y) - } - } - // Round 4 - for (y in for_y_start - overscan_open..for_y_end) { - for (x in for_x_end + overscan_open downTo for_x_start) { - calculateAndAssign(lightmap, x, y) - } - } - // Round 1 - for (y in for_y_start - overscan_open..for_y_end) { - for (x in for_x_start - overscan_open..for_x_end) { - calculateAndAssign(lightmap, x, y) - } - } - // Round 2 again - /*for (y in for_y_end + overscan_open downTo for_y_start) { - for (x in for_x_start - overscan_open..for_x_end) { - calculateAndAssign(lightmap, x, y) - } - }*/ } - } - else if (world.worldIndex != -1) { // to avoid updating on the null world - TODO() + // Round 3 + for (y in for_y_end + overscan_open downTo for_y_start) { + for (x in for_x_end + overscan_open downTo for_x_start) { + calculateAndAssign(lightmap, x, y) + } + } + // Round 4 + for (y in for_y_start - overscan_open..for_y_end) { + for (x in for_x_end + overscan_open downTo for_x_start) { + calculateAndAssign(lightmap, x, y) + } + } + // Round 1 + for (y in for_y_start - overscan_open..for_y_end) { + for (x in for_x_start - overscan_open..for_x_end) { + calculateAndAssign(lightmap, x, y) + } + } + // Round 2 again + /*for (y in for_y_end + overscan_open downTo for_y_start) { + for (x in for_x_start - overscan_open..for_x_end) { + calculateAndAssign(lightmap, x, y) + } + }*/ } } - else { - AppLoader.measureDebugTime("Renderer.LightGPU") { - - // prepare necessary textures (lightmap, shademap) for the input. - for (ty in 0 until LIGHTMAP_HEIGHT) { - for (tx in 0 until LIGHTMAP_WIDTH) { - val wx = tx + for_x_start - overscan_open - val wy = ty + for_y_start - overscan_open - - // Several variables will be altered by this. See its documentation. - getLightsAndShades(wx, wy) - - texturedLightSourcePixmap.drawPixel(tx, ty, lightLevelThis.toRGBA()) - texturedShadeSourcePixmap.drawPixel(tx, ty, thisTileOpacity.toRGBA()) - - - - /*if (wy in for_y_start..for_y_end && wx in for_x_start..for_x_end) { - texturedLightSourcePixmap.drawPixel(tx, ty, 0x00FFFFFF) - } - else { - texturedLightSourcePixmap.drawPixel(tx, ty, 0xFF000000.toInt()) - }*/ - - } - } - - texturedLightSources.dispose() - texturedLightSources = Texture(texturedLightSourcePixmap) - - texturedShadeSources.dispose() - texturedShadeSources = Texture(texturedShadeSourcePixmap) - - - texturedLightMap.inAction(texturedLightCamera, null) { - gdxClearAndSetBlend(0f,0f,0f,0f) - Gdx.gl.glDisable(GL20.GL_BLEND) - - texturedShadeSources.bind(SHADEMAP_UNIT) - texturedLightSources.bind(LIGHTMAP_UNIT) - - lightCalcShader.begin() - // it seems that every time shader ends, uniforms reset themselves. - lightCalcShader.setUniformMatrix("u_projTrans", texturedLightCamera.combined) - lightCalcShader.setUniformf("outSize", LIGHTMAP_WIDTH.toFloat(), LIGHTMAP_HEIGHT.toFloat()) - lightCalcShader.setUniformi("shades", SHADEMAP_UNIT) - lightCalcShader.setUniformi("lights", LIGHTMAP_UNIT) - texturedLightQuad.render(lightCalcShader, GL20.GL_TRIANGLES) - lightCalcShader.end() - } - - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it - - - } + else if (world.worldIndex != -1) { // to avoid updating on the null world + TODO() } } @@ -680,47 +570,41 @@ object LightmapRenderer { val this_y_end = for_y_end// + overscan_open // wipe out beforehand. You DO need this - if (!SHADER_LIGHTING) { - lightBuffer.blending = Pixmap.Blending.None // gonna overwrite (remove this line causes the world to go bit darker) - lightBuffer.setColor(colourNull) - lightBuffer.fill() + lightBuffer.blending = Pixmap.Blending.None // gonna overwrite (remove this line causes the world to go bit darker) + lightBuffer.setColor(colourNull) + lightBuffer.fill() - // write to colour buffer - for (y in this_y_start..this_y_end) { - //println("y: $y, this_y_start: $this_y_start") - if (y == this_y_start && this_y_start == 0) { - //throw Error("Fuck hits again...") - } - - for (x in this_x_start..this_x_end) { - - val color = (getLightForOpaque(x, y) ?: Color(0f, 0f, 0f, 0f)).normaliseToHDR() - - lightBuffer.setColor(color) - - //lightBuffer.drawPixel(x - this_x_start, y - this_y_start) - - lightBuffer.drawPixel(x - this_x_start, lightBuffer.height - 1 - y + this_y_start) // flip Y - } + // write to colour buffer + for (y in this_y_start..this_y_end) { + //println("y: $y, this_y_start: $this_y_start") + if (y == this_y_start && this_y_start == 0) { + //throw Error("Fuck hits again...") } + for (x in this_x_start..this_x_end) { - // draw to the batch - _lightBufferAsTex.dispose() - _lightBufferAsTex = Texture(lightBuffer) - _lightBufferAsTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) + val color = (getLightForOpaque(x, y) ?: Color(0f, 0f, 0f, 0f)).normaliseToHDR() + lightBuffer.setColor(color) - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it - // we might not need shader here... - //batch.draw(lightBufferAsTex, 0f, 0f, lightBufferAsTex.width.toFloat(), lightBufferAsTex.height.toFloat()) - batch.draw(_lightBufferAsTex, 0f, 0f, _lightBufferAsTex.width * DRAW_TILE_SIZE, _lightBufferAsTex.height * DRAW_TILE_SIZE) - } - else { - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it - batch.draw(texturedLightMap.colorBufferTexture, -overscan_open * DRAW_TILE_SIZE, -overscan_open * DRAW_TILE_SIZE, texturedLightMap.width * DRAW_TILE_SIZE, texturedLightMap.height * DRAW_TILE_SIZE) + //lightBuffer.drawPixel(x - this_x_start, y - this_y_start) + + lightBuffer.drawPixel(x - this_x_start, lightBuffer.height - 1 - y + this_y_start) // flip Y + } } + + + // draw to the batch + _lightBufferAsTex.dispose() + _lightBufferAsTex = Texture(lightBuffer) + _lightBufferAsTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest) + + + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it + // we might not need shader here... + //batch.draw(lightBufferAsTex, 0f, 0f, lightBufferAsTex.width.toFloat(), lightBufferAsTex.height.toFloat()) + batch.draw(_lightBufferAsTex, 0f, 0f, _lightBufferAsTex.width * DRAW_TILE_SIZE, _lightBufferAsTex.height * DRAW_TILE_SIZE) } } diff --git a/work_files/UI/building_maker_UI.psd b/work_files/UI/building_maker_UI.psd index 83f775b72..8d05aee00 100644 --- a/work_files/UI/building_maker_UI.psd +++ b/work_files/UI/building_maker_UI.psd @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2fe5e7528689980e7d60f3fb045c8aac116e296144b297a2e9ad4f02128b5c07 -size 7249605 +oid sha256:313dd3d8ee7c4bc08a928cfc962b058e87a3e281ee7b9e968a010a9cfa68fd2d +size 7332611