mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 10:34:06 +09:00
buildingmaker penmenu; resolving mouse click clash between world and UIs
This commit is contained in:
Binary file not shown.
@@ -269,6 +269,7 @@ public class AppLoader implements ApplicationListener {
|
|||||||
public static int screenH = 0;
|
public static int screenH = 0;
|
||||||
|
|
||||||
public static Texture textureWhiteSquare;
|
public static Texture textureWhiteSquare;
|
||||||
|
public static Texture textureWhiteCircle;
|
||||||
|
|
||||||
private void initViewPort(int width, int height) {
|
private void initViewPort(int width, int height) {
|
||||||
// Set Y to point downwards
|
// Set Y to point downwards
|
||||||
@@ -506,19 +507,26 @@ public class AppLoader implements ApplicationListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IngameRenderer.INSTANCE.dispose();
|
IngameRenderer.INSTANCE.dispose();
|
||||||
|
PostProcessor.INSTANCE.dispose();
|
||||||
|
|
||||||
Terrarum.INSTANCE.dispose();
|
Terrarum.INSTANCE.dispose();
|
||||||
|
|
||||||
shaderBayerSkyboxFill.dispose();
|
shaderBayerSkyboxFill.dispose();
|
||||||
shaderHicolour.dispose();
|
shaderHicolour.dispose();
|
||||||
|
shaderPassthru.dispose();
|
||||||
shaderColLUT.dispose();
|
shaderColLUT.dispose();
|
||||||
|
|
||||||
assetManager.dispose();
|
assetManager.dispose();
|
||||||
fullscreenQuad.dispose();
|
fullscreenQuad.dispose();
|
||||||
|
logoBatch.dispose();
|
||||||
|
|
||||||
fontGame.dispose();
|
fontGame.dispose();
|
||||||
fontSmallNumbers.dispose();
|
fontSmallNumbers.dispose();
|
||||||
|
|
||||||
|
textureWhiteSquare.dispose();
|
||||||
|
textureWhiteCircle.dispose();
|
||||||
|
logo.getTexture().dispose();
|
||||||
|
|
||||||
ModMgr.INSTANCE.disposeMods();
|
ModMgr.INSTANCE.disposeMods();
|
||||||
|
|
||||||
// delete temp files
|
// 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 = new Texture(Gdx.files.internal("assets/graphics/ortho_line_tex_2px.tga"));
|
||||||
textureWhiteSquare.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
|
textureWhiteSquare.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest);
|
||||||
|
|
||||||
|
textureWhiteCircle = new Texture(Gdx.files.internal("assets/graphics/circle_512.tga"));
|
||||||
|
|
||||||
TextureRegionPack.Companion.setGlobalFlipY(true);
|
TextureRegionPack.Companion.setGlobalFlipY(true);
|
||||||
fontGame = new GameFontBase("assets/graphics/fonts/terrarum-sans-bitmap", false, true,
|
fontGame = new GameFontBase("assets/graphics/fonts/terrarum-sans-bitmap", false, true,
|
||||||
Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest, false, 256, false
|
Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest, false, 256, false
|
||||||
|
|||||||
@@ -37,6 +37,15 @@ object PostProcessor {
|
|||||||
|
|
||||||
private val debugUI = BasicDebugInfoWindow()
|
private val debugUI = BasicDebugInfoWindow()
|
||||||
|
|
||||||
|
fun dispose() {
|
||||||
|
batch.dispose()
|
||||||
|
shapeRenderer.dispose()
|
||||||
|
try {
|
||||||
|
lutTex.dispose()
|
||||||
|
}
|
||||||
|
catch (e: UninitializedPropertyAccessException) { }
|
||||||
|
}
|
||||||
|
|
||||||
fun draw(projMat: Matrix4, fbo: FrameBuffer) {
|
fun draw(projMat: Matrix4, fbo: FrameBuffer) {
|
||||||
|
|
||||||
// init
|
// init
|
||||||
|
|||||||
@@ -509,6 +509,9 @@ fun Float.round(): Float {
|
|||||||
fun SpriteBatch.fillRect(x: Float, y: Float, w: Float, h: Float) {
|
fun SpriteBatch.fillRect(x: Float, y: Float, w: Float, h: Float) {
|
||||||
this.draw(AppLoader.textureWhiteSquare, x, y, w, h)
|
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) {
|
fun SpriteBatch.drawStraightLine(x: Float, y: Float, otherEnd: Float, thickness: Float, isVertical: Boolean) {
|
||||||
if (!isVertical)
|
if (!isVertical)
|
||||||
this.fillRect(x, y, otherEnd - x, thickness)
|
this.fillRect(x, y, otherEnd - x, thickness)
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ object BlockCodex {
|
|||||||
|
|
||||||
private var blockProps: Array<BlockProp>
|
private var blockProps: Array<BlockProp>
|
||||||
|
|
||||||
const val TILE_UNIQUE_MAX = MapLayer.RANGE * PairedMapLayer.RANGE
|
const val MAX_TERRAIN_TILES = MapLayer.RANGE * PairedMapLayer.RANGE
|
||||||
|
|
||||||
private val nullProp = BlockProp()
|
private val nullProp = BlockProp()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
blockProps = Array<BlockProp>(TILE_UNIQUE_MAX * 2, { BlockProp() })
|
blockProps = Array<BlockProp>(MAX_TERRAIN_TILES * 2, { BlockProp() })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
import net.torvald.terrarum.gameactors.*
|
import net.torvald.terrarum.gameactors.*
|
||||||
|
import net.torvald.terrarum.itemproperties.ItemID
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||||
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
|
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
|
||||||
import net.torvald.terrarum.modulebasegame.gameworld.WorldTime
|
import net.torvald.terrarum.modulebasegame.gameworld.WorldTime
|
||||||
@@ -33,12 +35,17 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
- Import…
|
- Import…
|
||||||
- Save terrain…
|
- Save terrain…
|
||||||
- Load terrain…
|
- Load terrain…
|
||||||
|
-
|
||||||
- Exit to Title : net.torvald.terrarum.modulebasegame.YamlCommandExit
|
- Exit to Title : net.torvald.terrarum.modulebasegame.YamlCommandExit
|
||||||
- Tool
|
- Tool
|
||||||
- Pencil : net.torvald.terrarum.modulebasegame.YamlCommandToolPencil
|
- Pencil : net.torvald.terrarum.modulebasegame.YamlCommandToolPencil
|
||||||
- Eyedropper
|
- Eraser : net.torvald.terrarum.modulebasegame.YamlCommandToolPencilErase
|
||||||
- Select mrq. : net.torvald.terrarum.modulebasegame.YamlCommandToolMarquee
|
- Wall Hammer : net.torvald.terrarum.modulebasegame.YamlCommandToolPencilEraseWall
|
||||||
- Move
|
- 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
|
- Undo
|
||||||
- Redo
|
- Redo
|
||||||
- Time
|
- Time
|
||||||
@@ -84,12 +91,15 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
val notifier = Notification()
|
val notifier = Notification()
|
||||||
val uiPaletteSelector = UIPaletteSelector(this)
|
val uiPaletteSelector = UIPaletteSelector(this)
|
||||||
val uiPalette = UIBuildingMakerBlockChooser(this)
|
val uiPalette = UIBuildingMakerBlockChooser(this)
|
||||||
|
val uiPenMenu = UIBuildingMakerPenMenu(this)
|
||||||
|
|
||||||
|
|
||||||
val uiContainer = ArrayList<UICanvas>()
|
val uiContainer = ArrayList<UICanvas>()
|
||||||
|
|
||||||
var currentPenMode = PENMODE_PENCIL
|
var currentPenMode = PENMODE_PENCIL
|
||||||
|
var currentPenTarget = PENTARGET_TERRAIN
|
||||||
|
|
||||||
|
val selection = ArrayList<Point2i>()
|
||||||
|
|
||||||
val blockPointingCursor = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
val blockPointingCursor = object : ActorWithBody(Actor.RenderOrder.OVERLAY) {
|
||||||
|
|
||||||
@@ -130,11 +140,20 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val PENMODE_PENCIL = 0
|
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(
|
val toolCursorColour = arrayOf(
|
||||||
Color.YELLOW,
|
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(uiPaletteSelector)
|
||||||
uiContainer.add(notifier)
|
uiContainer.add(notifier)
|
||||||
uiContainer.add(uiPalette)
|
uiContainer.add(uiPalette)
|
||||||
|
uiContainer.add(uiPenMenu)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -168,7 +188,6 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
|
|
||||||
uiPalette.setPosition(200, 100)
|
uiPalette.setPosition(200, 100)
|
||||||
uiPalette.isVisible = true // TEST CODE should not be visible
|
|
||||||
|
|
||||||
|
|
||||||
LightmapRenderer.fireRecalculateEvent()
|
LightmapRenderer.fireRecalculateEvent()
|
||||||
@@ -206,30 +225,47 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateGame(delta: Float) {
|
private var mouseOnUI = false
|
||||||
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)
|
WeatherMixer.update(delta, actorNowPlaying, gameWorld)
|
||||||
blockPointingCursor.update(delta)
|
blockPointingCursor.update(delta)
|
||||||
actorNowPlaying?.update(delta)
|
actorNowPlaying?.update(delta)
|
||||||
|
var overwriteMouseOnUI = false
|
||||||
uiContainer.forEach {
|
uiContainer.forEach {
|
||||||
it.update(delta)
|
it.update(delta)
|
||||||
if (it.isVisible && it.mouseUp) {
|
if (it.isVisible && it.mouseUp) {
|
||||||
mouseOnUI = true
|
overwriteMouseOnUI = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mouseOnUI = (overwriteMouseOnUI || uiPenMenu.isVisible)
|
||||||
|
|
||||||
|
|
||||||
WorldCamera.update(world, actorNowPlaying)
|
WorldCamera.update(world, actorNowPlaying)
|
||||||
|
|
||||||
|
|
||||||
// make pen work HERE
|
// 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)
|
makePenWork(Terrarum.mouseTileX, Terrarum.mouseTileY)
|
||||||
// TODO drag support using bresenham's algo
|
// TODO drag support using bresenham's algo
|
||||||
// for some reason it just doesn't work...
|
// 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")
|
println("[BuildingMaker] Resize event")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setPencilColour(itemID: ItemID) {
|
||||||
|
uiPaletteSelector.fore = itemID
|
||||||
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
blockPointingCursor.dispose()
|
blockPointingCursor.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makePenWork(worldTileX: Int, worldTileY: Int) {
|
private fun makePenWork(x: Int, y: Int) {
|
||||||
val world = gameWorld
|
val world = gameWorld
|
||||||
val palSelection = uiPaletteSelector.fore
|
val palSelection = uiPaletteSelector.fore
|
||||||
|
|
||||||
when (currentPenMode) {
|
when (currentPenMode) {
|
||||||
// test paint terrain layer
|
// test paint terrain layer
|
||||||
PENMODE_PENCIL -> {
|
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() {
|
class BuildingMakerController(val screen: BuildingMaker) : InputAdapter() {
|
||||||
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
screen.uiContainer.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
screen.uiContainer.forEach { it.touchUp(screenX, screenY, pointer, button) }
|
||||||
|
screen.tappedOnUI = false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +345,6 @@ class BuildingMakerController(val screen: BuildingMaker) : InputAdapter() {
|
|||||||
return true
|
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 {
|
override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean {
|
||||||
screen.uiContainer.forEach { it.touchDragged(screenX, screenY, pointer) }
|
screen.uiContainer.forEach { it.touchDragged(screenX, screenY, pointer) }
|
||||||
return true
|
return true
|
||||||
@@ -368,6 +423,28 @@ class YamlCommandSetTimeNight : YamlInvokable {
|
|||||||
class YamlCommandToolPencil : YamlInvokable {
|
class YamlCommandToolPencil : YamlInvokable {
|
||||||
override fun invoke(args: Array<Any>) {
|
override fun invoke(args: Array<Any>) {
|
||||||
(args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_PENCIL
|
(args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_PENCIL
|
||||||
|
(args[0] as BuildingMaker).currentPenTarget = BuildingMaker.PENTARGET_TERRAIN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class YamlCommandToolPencilErase : YamlInvokable {
|
||||||
|
override fun invoke(args: Array<Any>) {
|
||||||
|
(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<Any>) {
|
||||||
|
(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<Any>) {
|
||||||
|
(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<Any>) {
|
override fun invoke(args: Array<Any>) {
|
||||||
(args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_MARQUEE
|
(args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_MARQUEE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class YamlCommandToolMarqueeErase : YamlInvokable {
|
||||||
|
override fun invoke(args: Array<Any>) {
|
||||||
|
(args[0] as BuildingMaker).currentPenMode = BuildingMaker.PENMODE_MARQUEE_ERASE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import net.torvald.terrarum.gameactors.ActorWBMovable
|
|||||||
import net.torvald.terrarum.itemproperties.GameItem
|
import net.torvald.terrarum.itemproperties.GameItem
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
import net.torvald.terrarum.itemproperties.Material
|
import net.torvald.terrarum.itemproperties.Material
|
||||||
|
import net.torvald.terrarum.modulebasegame.imagefont.WatchFont
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The entry point for the module "Basegame"
|
* The entry point for the module "Basegame"
|
||||||
@@ -103,4 +104,7 @@ class EntryPoint : ModuleEntryPoint() {
|
|||||||
println("Welcome back!")
|
println("Welcome back!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
WatchFont.dispose()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -588,6 +588,8 @@ object IngameRenderer {
|
|||||||
LightmapRenderer.dispose()
|
LightmapRenderer.dispose()
|
||||||
BlocksDrawer.dispose()
|
BlocksDrawer.dispose()
|
||||||
WeatherMixer.dispose()
|
WeatherMixer.dispose()
|
||||||
|
|
||||||
|
batch.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun worldCamToRenderPos(): Pair<Float, Float> {
|
private fun worldCamToRenderPos(): Pair<Float, Float> {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package net.torvald.terrarum.modulebasegame
|
|||||||
import com.badlogic.gdx.graphics.Camera
|
import com.badlogic.gdx.graphics.Camera
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
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.fillRect
|
||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
@@ -21,7 +23,7 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() {
|
|||||||
|
|
||||||
const val TILESREGION_SIZE = 24
|
const val TILESREGION_SIZE = 24
|
||||||
const val MENUBAR_SIZE = 80
|
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 WIDTH = TILES_X*TILESREGION_SIZE + SCROLLBAR_SIZE + MENUBAR_SIZE
|
||||||
const val HEIGHT = TILES_Y*TILESREGION_SIZE
|
const val HEIGHT = TILES_Y*TILESREGION_SIZE
|
||||||
@@ -60,14 +62,31 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() {
|
|||||||
palette.forEach { it.update(delta) }
|
palette.forEach { it.update(delta) }
|
||||||
tabs.update(delta)
|
tabs.update(delta)
|
||||||
closeButton.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) {
|
override fun renderUI(batch: SpriteBatch, camera: Camera) {
|
||||||
palette.forEach { it.render(batch, camera) }
|
palette.forEach { it.render(batch, camera) }
|
||||||
|
|
||||||
// gaps between tabs and close button
|
// gaps between tabs and close button
|
||||||
batch.color = DEFAULT_BACKGROUNDCOL
|
batch.color = DEFAULT_BACKGROUNDCOL
|
||||||
batch.fillRect(0f, tabs.height.toFloat(), MENUBAR_SIZE.toFloat(), height.toFloat() - (tabs.height + closeButton.height))
|
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
|
// the actual buttons
|
||||||
tabs.render(batch, camera)
|
tabs.render(batch, camera)
|
||||||
@@ -77,7 +96,6 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() {
|
|||||||
private var dragOriginX = 0 // relative mousepos
|
private var dragOriginX = 0 // relative mousepos
|
||||||
private var dragOriginY = 0 // relative mousepos
|
private var dragOriginY = 0 // relative mousepos
|
||||||
private var dragForReal = false
|
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
|
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
|
dragOriginX = relativeMouseX
|
||||||
dragOriginY = relativeMouseY
|
dragOriginY = relativeMouseY
|
||||||
dragForReal = true
|
dragForReal = true
|
||||||
|
parent.tappedOnUI = true
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dragForReal = false
|
dragForReal = false
|
||||||
}
|
}
|
||||||
|
|
||||||
closeReady = closeButton.mouseUp
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
override fun touchUp(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
if (closeReady && closeButton.mouseUp) {
|
|
||||||
closeButton.deselect()
|
|
||||||
this.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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<Vector2>(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() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import net.torvald.terrarum.itemproperties.GameItem
|
|||||||
import net.torvald.terrarum.itemproperties.ItemCodex
|
import net.torvald.terrarum.itemproperties.ItemCodex
|
||||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2016-03-15.
|
* Created by minjaesong on 2016-03-15.
|
||||||
@@ -18,7 +17,7 @@ open class DroppedItem(private val item: GameItem) : ActorWBMovable(RenderOrder.
|
|||||||
|
|
||||||
isVisible = true
|
isVisible = true
|
||||||
|
|
||||||
avBaseMass = if (item.dynamicID < BlockCodex.TILE_UNIQUE_MAX)
|
avBaseMass = if (item.dynamicID < BlockCodex.MAX_TERRAIN_TILES)
|
||||||
BlockCodex[item.dynamicID].density / 1000.0
|
BlockCodex[item.dynamicID].density / 1000.0
|
||||||
else
|
else
|
||||||
ItemCodex[item.dynamicID].mass
|
ItemCodex[item.dynamicID].mass
|
||||||
|
|||||||
@@ -873,6 +873,10 @@ internal object BlocksDrawer {
|
|||||||
tilesWire.dispose()
|
tilesWire.dispose()
|
||||||
tileItemWall.dispose()
|
tileItemWall.dispose()
|
||||||
tilesFluid.dispose()
|
tilesFluid.dispose()
|
||||||
|
tilesBuffer.dispose()
|
||||||
|
_tilesBufferAsTex.dispose()
|
||||||
|
tilesQuad.dispose()
|
||||||
|
shader.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRenderStartX(): Int = WorldCamera.x / TILE_SIZE
|
fun getRenderStartX(): Int = WorldCamera.x / TILE_SIZE
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package net.torvald.terrarum.worlddrawer
|
package net.torvald.terrarum.worlddrawer
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
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.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
|
||||||
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
import com.badlogic.gdx.graphics.glutils.ShaderProgram
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
@@ -38,7 +40,7 @@ object LightmapRenderer {
|
|||||||
|
|
||||||
private var world: GameWorld = GameWorld.makeNullWorld()
|
private var world: GameWorld = GameWorld.makeNullWorld()
|
||||||
private lateinit var lightCalcShader: ShaderProgram
|
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! */
|
/** do not call this yourself! Let your game renderer handle this! */
|
||||||
fun setWorld(world: GameWorld) {
|
fun setWorld(world: GameWorld) {
|
||||||
@@ -86,62 +88,8 @@ object LightmapRenderer {
|
|||||||
private val lightmap: Array<Color> = 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 lightmap: Array<Color> = 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<BlockAddress, Color>((Terrarum.ingame?.ACTORCONTAINER_INITIAL_SIZE ?: 2) * 4)
|
private val lanternMap = HashMap<BlockAddress, Color>((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 {
|
init {
|
||||||
printdbg(this, "Overscan open: $overscan_open; opaque: $overscan_opaque")
|
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
|
private val AIR = Block.AIR
|
||||||
@@ -260,139 +208,81 @@ object LightmapRenderer {
|
|||||||
buildLanternmap(actorContainers)
|
buildLanternmap(actorContainers)
|
||||||
} // usually takes 3000 ns
|
} // usually takes 3000 ns
|
||||||
|
|
||||||
if (!SHADER_LIGHTING) {
|
/*
|
||||||
/*
|
* Updating order:
|
||||||
* Updating order:
|
* ,--------. ,--+-----. ,-----+--. ,--------. -
|
||||||
* ,--------. ,--+-----. ,-----+--. ,--------. -
|
* |↘ | | | 3| |3 | | | ↙| ↕︎ overscan_open / overscan_opaque
|
||||||
* |↘ | | | 3| |3 | | | ↙| ↕︎ overscan_open / overscan_opaque
|
* | ,-----+ | | 2 | | 2 | | +-----. | - depending on the noop_mask
|
||||||
* | ,-----+ | | 2 | | 2 | | +-----. | - depending on the noop_mask
|
* | |1 | | |1 | | 1| | | 1| |
|
||||||
* | |1 | | |1 | | 1| | | 1| |
|
* | | 2 | | `-----+ +-----' | | 2 | |
|
||||||
* | | 2 | | `-----+ +-----' | | 2 | |
|
* | | 3| |↗ | | ↖| |3 | |
|
||||||
* | | 3| |↗ | | ↖| |3 | |
|
* `--+-----' `--------' `--------' `-----+--'
|
||||||
* `--+-----' `--------' `--------' `-----+--'
|
* round: 1 2 3 4
|
||||||
* round: 1 2 3 4
|
* for all lightmap[y][x], run in this order: 2-3-4-1
|
||||||
* 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,
|
||||||
* If you run only 4 sets, orthogonal/diagonal artefacts are bound to occur,
|
*/
|
||||||
*/
|
|
||||||
|
|
||||||
// set sunlight
|
// set sunlight
|
||||||
sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT)
|
sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT)
|
||||||
|
|
||||||
// set no-op mask from solidity of the block
|
// set no-op mask from solidity of the block
|
||||||
AppLoader.measureDebugTime("Renderer.LightNoOpMask") {
|
AppLoader.measureDebugTime("Renderer.LightNoOpMask") {
|
||||||
noopMask.clear()
|
noopMask.clear()
|
||||||
buildNoopMask()
|
buildNoopMask()
|
||||||
}
|
}
|
||||||
|
|
||||||
// wipe out lightmap
|
// wipe out lightmap
|
||||||
AppLoader.measureDebugTime("Renderer.Light0") {
|
AppLoader.measureDebugTime("Renderer.Light0") {
|
||||||
for (k in 0 until lightmap.size) lightmap[k] = colourNull
|
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
|
// 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
|
// 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.
|
// 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
|
// 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,
|
// The skipping is dependent on how you get ambient light,
|
||||||
// in this case we have 'spillage' due to the fact calculate() samples 3x3 area.
|
// in this case we have 'spillage' due to the fact calculate() samples 3x3 area.
|
||||||
|
|
||||||
AppLoader.measureDebugTime("Renderer.LightTotal") {
|
AppLoader.measureDebugTime("Renderer.LightTotal") {
|
||||||
// Round 2
|
// Round 2
|
||||||
for (y in for_y_end + overscan_open downTo for_y_start) {
|
for (y in for_y_end + overscan_open downTo for_y_start) {
|
||||||
for (x in for_x_start - overscan_open..for_x_end) {
|
for (x in for_x_start - overscan_open..for_x_end) {
|
||||||
calculateAndAssign(lightmap, x, y)
|
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)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
// Round 3
|
||||||
else if (world.worldIndex != -1) { // to avoid updating on the null world
|
for (y in for_y_end + overscan_open downTo for_y_start) {
|
||||||
TODO()
|
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 {
|
else if (world.worldIndex != -1) { // to avoid updating on the null world
|
||||||
AppLoader.measureDebugTime("Renderer.LightGPU") {
|
TODO()
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,47 +570,41 @@ object LightmapRenderer {
|
|||||||
val this_y_end = for_y_end// + overscan_open
|
val this_y_end = for_y_end// + overscan_open
|
||||||
|
|
||||||
// wipe out beforehand. You DO need this
|
// 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.blending = Pixmap.Blending.None // gonna overwrite (remove this line causes the world to go bit darker)
|
lightBuffer.setColor(colourNull)
|
||||||
lightBuffer.setColor(colourNull)
|
lightBuffer.fill()
|
||||||
lightBuffer.fill()
|
|
||||||
|
|
||||||
|
|
||||||
// write to colour buffer
|
// write to colour buffer
|
||||||
for (y in this_y_start..this_y_end) {
|
for (y in this_y_start..this_y_end) {
|
||||||
//println("y: $y, this_y_start: $this_y_start")
|
//println("y: $y, this_y_start: $this_y_start")
|
||||||
if (y == this_y_start && this_y_start == 0) {
|
if (y == this_y_start && this_y_start == 0) {
|
||||||
//throw Error("Fuck hits again...")
|
//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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (x in this_x_start..this_x_end) {
|
||||||
|
|
||||||
// draw to the batch
|
val color = (getLightForOpaque(x, y) ?: Color(0f, 0f, 0f, 0f)).normaliseToHDR()
|
||||||
_lightBufferAsTex.dispose()
|
|
||||||
_lightBufferAsTex = Texture(lightBuffer)
|
|
||||||
_lightBufferAsTex.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
|
|
||||||
|
|
||||||
|
lightBuffer.setColor(color)
|
||||||
|
|
||||||
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it
|
//lightBuffer.drawPixel(x - this_x_start, y - this_y_start)
|
||||||
// we might not need shader here...
|
|
||||||
//batch.draw(lightBufferAsTex, 0f, 0f, lightBufferAsTex.width.toFloat(), lightBufferAsTex.height.toFloat())
|
lightBuffer.drawPixel(x - this_x_start, lightBuffer.height - 1 - y + this_y_start) // flip Y
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user