LibGDX, here I am.

This commit is contained in:
minjaesong
2017-06-22 02:31:07 +09:00
parent ae00e2b8a6
commit 8e5e95e5a9
356 changed files with 3125 additions and 21138 deletions

View File

@@ -1,784 +0,0 @@
package net.torvald.terrarum.worlddrawer
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.PairedMapLayer
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.blockproperties.BlockCodex
import com.jme3.math.FastMath
import net.torvald.terrarum.*
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.itemproperties.ItemCodex.ITEM_TILES
import net.torvald.terrarum.worlddrawer.WorldCamera.x
import net.torvald.terrarum.worlddrawer.WorldCamera.y
import net.torvald.terrarum.worlddrawer.WorldCamera.height
import net.torvald.terrarum.worlddrawer.WorldCamera.width
import org.lwjgl.BufferUtils
import org.lwjgl.opengl.*
import org.newdawn.slick.*
import java.nio.ByteBuffer
import java.nio.FloatBuffer
/**
* Created by minjaesong on 16-01-19.
*/
object BlocksDrawer_NEW {
private val world: GameWorld = Terrarum.ingame!!.world
private val TILE_SIZE = FeaturesDrawer.TILE_SIZE
private val TILE_SIZEF = FeaturesDrawer.TILE_SIZE.toFloat()
// TODO modular
val tilesTerrain = SpriteSheet(ModMgr.getPath("basegame", "blocks/terrain.tga.gz"), TILE_SIZE, TILE_SIZE) // 64 MB
val terrainHorizontalTiles = tilesTerrain.horizontalCount
val tilesWire = SpriteSheet(ModMgr.getPath("basegame", "blocks/wire.tga.gz"), TILE_SIZE, TILE_SIZE) // 4 MB
val wireHorizontalTiles = tilesWire.horizontalCount
val tilesTerrainTexBuffer: ByteBuffer = BufferUtils.createByteBuffer(tilesTerrain.texture.textureData.size)
init {
tilesTerrainTexBuffer.put(tilesTerrain.texture.textureData)
tilesTerrainTexBuffer.rewind()
}
val tileItemWall = Image(TILE_SIZE * 16, TILE_SIZE * GameWorld.TILES_SUPPORTED / 16) // 4 MB
val wallOverlayColour = Color(2f/3f, 2f/3f, 2f/3f, 1f)
val breakAnimSteps = 10
val WALL = GameWorld.WALL
val TERRAIN = GameWorld.TERRAIN
val WIRE = GameWorld.WIRE
private val NEARBY_TILE_KEY_UP = 0
private val NEARBY_TILE_KEY_RIGHT = 1
private val NEARBY_TILE_KEY_DOWN = 2
private val NEARBY_TILE_KEY_LEFT = 3
private val NEARBY_TILE_CODE_UP = 1
private val NEARBY_TILE_CODE_RIGHT = 2
private val NEARBY_TILE_CODE_DOWN = 4
private val NEARBY_TILE_CODE_LEFT = 8
val VBO_WIDTH = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.WIDTH).div(TILE_SIZE).ceil() + 3
val VBO_HEIGHT = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.HEIGHT).div(TILE_SIZE).ceil() + 3
val cameraTileX: Int
get() = WorldCamera.x.div(TILE_SIZE)
val cameraTileY: Int
get() = WorldCamera.y.div(TILE_SIZE)
/**
* Stores which tile on the SpriteSheet should be drawn, to feed them into the VBO
* valid values: 0-65535
*/
val regionBuffer = Array(VBO_HEIGHT) { IntArray(VBO_WIDTH) }
fun writeToRegionBuffer(tilewisePosX: Int, tilewisePosY: Int, sheetX: Int, sheetY: Int) {
regionBuffer[tilewisePosY - cameraTileY + 1][tilewisePosX - cameraTileX + 1] = sheetY * terrainHorizontalTiles + sheetX
}
val worldVBOTexture: FloatBuffer // stores texture offset
val worldVBOTextureID: Int
val worldVBOVertex: FloatBuffer // stores points that holds x-y positions
val worldVBOVertexID: Int
/* Have only 1 dynamic VBO and change its vertices every frame according to the visible tiles on screen.
* This method will safe overhead from binding / unbinding different VBO's. Uploading vertices in a batch is also pretty fast.
*
* For good performance always remember:
* batch batch batch batch batch.
*/
init {
val tg = tileItemWall.graphics
// initialise item_wall images
(ITEM_TILES).forEach {
tg.drawImage(
tilesTerrain.getSubImage(
(it % 16) * 16,
(it / 16)
),
(it % 16) * TILE_SIZE.toFloat(),
(it / 16) * TILE_SIZE.toFloat(),
wallOverlayColour
)
}
//tg.flush()
//ImageOut.write(tileItemWall, "./tileitemwalltest.png")
tg.destroy()
// generate VBO
worldVBOTexture = BufferUtils.createFloatBuffer(8 * VBO_WIDTH * VBO_HEIGHT)
worldVBOVertex = BufferUtils.createFloatBuffer(8 * VBO_WIDTH * VBO_HEIGHT)
for (y in 0..VBO_HEIGHT - 1) {
for (x in 0..VBO_WIDTH - 1) {
val x = x * TILE_SIZEF
val y = y * TILE_SIZEF
worldVBOVertex.put(floatArrayOf( // fixed points (triangles); won't need to be re-assigned
//x , y ,
//x + TILE_SIZEF, y ,
//x , y + TILE_SIZEF,
//x + TILE_SIZEF, y ,
//x + TILE_SIZEF, y + TILE_SIZEF,
//x , y + TILE_SIZEF
x, y,
x + TILE_SIZEF, y,
x + TILE_SIZEF, y + TILE_SIZEF,
x, y + TILE_SIZEF
))
}
}
worldVBOVertex.rewind()
worldVBOVertexID = GL15.glGenBuffers()
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOVertexID) //Bind buffer (also specifies type of buffer)
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, worldVBOVertex, GL15.GL_STATIC_DRAW) //Send up the data and specify usage hint.
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0)
worldVBOTextureID = GL15.glGenBuffers()
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOTextureID) //Bind buffer (also specifies type of buffer)
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, worldVBOTexture, GL15.GL_DYNAMIC_DRAW) //Send up the data and specify usage hint.
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0)
}
/**
* Connectivity group 01 : artificial tiles
* It holds different shading rule to discriminate with group 02, index 0 is single tile.
* These are the tiles that only connects to itself, will not connect to colour variants
*/
private val TILES_CONNECT_SELF = hashSetOf(
Block.GLASS_CRUDE,
Block.GLASS_CLEAN,
Block.ILLUMINATOR_BLACK,
Block.ILLUMINATOR_BLUE,
Block.ILLUMINATOR_BROWN,
Block.ILLUMINATOR_CYAN,
Block.ILLUMINATOR_FUCHSIA,
Block.ILLUMINATOR_GREEN,
Block.ILLUMINATOR_GREEN_DARK,
Block.ILLUMINATOR_GREY_DARK,
Block.ILLUMINATOR_GREY_LIGHT,
Block.ILLUMINATOR_GREY_MED,
Block.ILLUMINATOR_ORANGE,
Block.ILLUMINATOR_PURPLE,
Block.ILLUMINATOR_RED,
Block.ILLUMINATOR_TAN,
Block.ILLUMINATOR_WHITE,
Block.ILLUMINATOR_YELLOW,
Block.ILLUMINATOR_BLACK_OFF,
Block.ILLUMINATOR_BLUE_OFF,
Block.ILLUMINATOR_BROWN_OFF,
Block.ILLUMINATOR_CYAN_OFF,
Block.ILLUMINATOR_FUCHSIA_OFF,
Block.ILLUMINATOR_GREEN_OFF,
Block.ILLUMINATOR_GREEN_DARK_OFF,
Block.ILLUMINATOR_GREY_DARK_OFF,
Block.ILLUMINATOR_GREY_LIGHT_OFF,
Block.ILLUMINATOR_GREY_MED_OFF,
Block.ILLUMINATOR_ORANGE_OFF,
Block.ILLUMINATOR_PURPLE_OFF,
Block.ILLUMINATOR_RED_OFF,
Block.ILLUMINATOR_TAN_OFF,
Block.ILLUMINATOR_WHITE_OFF,
Block.ILLUMINATOR_YELLOW,
Block.DAYLIGHT_CAPACITOR
)
/**
* To interact with external modules
*/
@JvmStatic fun addConnectSelf(blockID: Int): Boolean {
return TILES_CONNECT_SELF.add(blockID)
}
/**
* Connectivity group 02 : natural tiles
* It holds different shading rule to discriminate with group 01, index 0 is middle tile.
*/
private val TILES_CONNECT_MUTUAL = hashSetOf(
Block.STONE,
Block.STONE_QUARRIED,
Block.STONE_TILE_WHITE,
Block.STONE_BRICKS,
Block.DIRT,
Block.GRASS,
Block.GRASSWALL,
Block.PLANK_BIRCH,
Block.PLANK_BLOODROSE,
Block.PLANK_EBONY,
Block.PLANK_NORMAL,
Block.SAND,
Block.SAND_WHITE,
Block.SAND_RED,
Block.SAND_DESERT,
Block.SAND_BLACK,
Block.SAND_GREEN,
Block.GRAVEL,
Block.GRAVEL_GREY,
Block.SNOW,
Block.ICE_NATURAL,
Block.ICE_MAGICAL,
Block.ORE_COPPER,
Block.ORE_IRON,
Block.ORE_GOLD,
Block.ORE_SILVER,
Block.ORE_ILMENITE,
Block.ORE_AURICHALCUM,
Block.SANDSTONE,
Block.SANDSTONE_BLACK,
Block.SANDSTONE_DESERT,
Block.SANDSTONE_RED,
Block.SANDSTONE_WHITE,
Block.SANDSTONE_GREEN,
Block.WATER,
Block.WATER_1,
Block.WATER_2,
Block.WATER_3,
Block.WATER_4,
Block.WATER_5,
Block.WATER_6,
Block.WATER_7,
Block.WATER_8,
Block.WATER_9,
Block.WATER_10,
Block.WATER_11,
Block.WATER_12,
Block.WATER_13,
Block.WATER_14,
Block.WATER_15,
Block.LAVA,
Block.LAVA_1,
Block.LAVA_2,
Block.LAVA_3,
Block.LAVA_4,
Block.LAVA_5,
Block.LAVA_6,
Block.LAVA_7,
Block.LAVA_8,
Block.LAVA_9,
Block.LAVA_10,
Block.LAVA_11,
Block.LAVA_12,
Block.LAVA_13,
Block.LAVA_14,
Block.LAVA_15
)
/**
* To interact with external modules
*/
@JvmStatic fun addConnectMutual(blockID: Int): Boolean {
return TILES_CONNECT_MUTUAL.add(blockID)
}
/**
* Torches, levers, switches, ...
*/
private val TILES_WALL_STICKER = hashSetOf(
Block.TORCH,
Block.TORCH_FROST,
Block.TORCH_OFF,
Block.TORCH_FROST_OFF
)
/**
* To interact with external modules
*/
@JvmStatic fun addWallSticker(blockID: Int): Boolean {
return TILES_WALL_STICKER.add(blockID)
}
/**
* platforms, ...
*/
private val TILES_WALL_STICKER_CONNECT_SELF = hashSetOf(
Block.PLATFORM_BIRCH,
Block.PLATFORM_BLOODROSE,
Block.PLATFORM_EBONY,
Block.PLATFORM_STONE,
Block.PLATFORM_WOODEN
)
/**
* To interact with external modules
*/
@JvmStatic fun addWallStickerConnectSelf(blockID: Int): Boolean {
return TILES_WALL_STICKER_CONNECT_SELF.add(blockID)
}
/**
* Tiles that half-transparent and has hue
* will blend colour using colour multiplication
* i.e. red hues get lost if you dive into the water
*/
private val TILES_BLEND_MUL = hashSetOf(
Block.WATER,
Block.WATER_1,
Block.WATER_2,
Block.WATER_3,
Block.WATER_4,
Block.WATER_5,
Block.WATER_6,
Block.WATER_7,
Block.WATER_8,
Block.WATER_9,
Block.WATER_10,
Block.WATER_11,
Block.WATER_12,
Block.WATER_13,
Block.WATER_14,
Block.WATER_15,
Block.LAVA,
Block.LAVA_1,
Block.LAVA_2,
Block.LAVA_3,
Block.LAVA_4,
Block.LAVA_5,
Block.LAVA_6,
Block.LAVA_7,
Block.LAVA_8,
Block.LAVA_9,
Block.LAVA_10,
Block.LAVA_11,
Block.LAVA_12,
Block.LAVA_13,
Block.LAVA_14,
Block.LAVA_15
)
/**
* To interact with external modules
*/
@JvmStatic fun addBlendMul(blockID: Int): Boolean {
return TILES_BLEND_MUL.add(blockID)
}
fun renderWall(g: Graphics) {
/**
* render to camera
*/
blendNormal()
//tilesTerrain.startUse()
drawTiles(g, WALL, false)
//tilesTerrain.endUse()
blendMul()
g.color = wallOverlayColour
g.fillRect(WorldCamera.x.toFloat(), WorldCamera.y.toFloat(),
WorldCamera.width.toFloat() + 1, WorldCamera.height.toFloat() + 1
)
blendNormal()
}
fun renderTerrain(g: Graphics) {
/**
* render to camera
*/
blendNormal()
//tilesTerrain.startUse()
drawTiles(g, TERRAIN, false) // regular tiles
//tilesTerrain.endUse()
}
fun renderFront(g: Graphics, drawWires: Boolean) {
/**
* render to camera
*/
blendMul()
//tilesTerrain.startUse()
drawTiles(g, TERRAIN, true) // blendmul tiles
//tilesTerrain.endUse()
if (drawWires) {
//tilesWire.startUse()
drawTiles(g, WIRE, false)
//tilesWire.endUse()
}
blendNormal()
}
private val tileDrawLightThreshold = 2
private fun drawTiles(g: Graphics, mode: Int, drawModeTilesBlendMul: Boolean) {
val for_y_start = y / TILE_SIZE
val for_y_end = BlocksDrawer.clampHTile(for_y_start + (height / TILE_SIZE) + 2)
val for_x_start = x / TILE_SIZE - 1
val for_x_end = for_x_start + (width / TILE_SIZE) + 3
var zeroTileCounter = 0
// draw - build VBO texture region table
for (y in for_y_start..for_y_end) {
for (x in for_x_start..for_x_end - 1) {
val thisTile: Int?
if (mode % 3 == WALL)
thisTile = world.getTileFromWall(x, y)
else if (mode % 3 == TERRAIN)
thisTile = world.getTileFromTerrain(x, y)
else if (mode % 3 == WIRE)
thisTile = world.getTileFromWire(x, y)
else
throw IllegalArgumentException()
val noDamageLayer = mode % 3 == WIRE
// draw a tile, but only when illuminated
try {
if ((mode == WALL || mode == TERRAIN) && // not an air tile
(thisTile ?: 0) != Block.AIR) {
// check if light level of nearby or this tile is illuminated
if ( LightmapRenderer.getHighestRGB(x, y) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x - 1, y) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x + 1, y) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x, y - 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x, y + 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x - 1, y - 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x + 1, y + 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x + 1, y - 1) ?: 0 >= tileDrawLightThreshold ||
LightmapRenderer.getHighestRGB(x - 1, y + 1) ?: 0 >= tileDrawLightThreshold) {
// blackness
if (zeroTileCounter > 0) {
/* unable to do anything */
zeroTileCounter = 0
}
val nearbyTilesInfo: Int
if (isPlatform(thisTile)) {
nearbyTilesInfo = getNearbyTilesInfoPlatform(x, y)
}
else if (isWallSticker(thisTile)) {
nearbyTilesInfo = getNearbyTilesInfoWallSticker(x, y)
}
else if (isConnectMutual(thisTile)) {
nearbyTilesInfo = getNearbyTilesInfoNonSolid(x, y, mode)
}
else if (isConnectSelf(thisTile)) {
nearbyTilesInfo = getNearbyTilesInfo(x, y, mode, thisTile)
}
else {
nearbyTilesInfo = 0
}
val thisTileX = if (!noDamageLayer)
PairedMapLayer.RANGE * ((thisTile ?: 0) % PairedMapLayer.RANGE) + nearbyTilesInfo
else
nearbyTilesInfo
val thisTileY = (thisTile ?: 0) / PairedMapLayer.RANGE
// draw a tile
if (drawModeTilesBlendMul) {
if (BlocksDrawer.isBlendMul(thisTile)) {
drawTile(mode, x, y, thisTileX, thisTileY)
}
}
else {
// do NOT add "if (!isBlendMul(thisTile))"!
// or else they will not look like they should be when backed with wall
drawTile(mode, x, y, thisTileX, thisTileY)
}
// draw a breakage
/*if (mode == TERRAIN || mode == WALL) {
val breakage = if (mode == TERRAIN) world.getTerrainDamage(x, y) else world.getWallDamage(x, y)
val maxHealth = BlockCodex[world.getTileFromTerrain(x, y)].strength
val stage = (breakage / maxHealth).times(breakAnimSteps).roundInt()
// actual drawing
if (stage > 0) {
// alpha blending works, but no GL blend func...
drawTile(mode, x, y, 5 + stage, 0)
}
}*/
} // end if (is illuminated)
// draw black patch
else {
zeroTileCounter++ // unused for now
/*GL11.glColor4f(0f, 0f, 0f, 1f)
GL11.glTexCoord2f(0f, 0f)
GL11.glVertex3f(x * TILE_SIZE.toFloat(), y * TILE_SIZE.toFloat(), 0f)
GL11.glTexCoord2f(0f, 0f + TILE_SIZE)
GL11.glVertex3f(x * TILE_SIZE.toFloat(), (y + 1) * TILE_SIZE.toFloat(), 0f)
GL11.glTexCoord2f(0f + TILE_SIZE, 0f + TILE_SIZE)
GL11.glVertex3f((x + 1) * TILE_SIZE.toFloat(), (y + 1) * TILE_SIZE.toFloat(), 0f)
GL11.glTexCoord2f(0f + TILE_SIZE, 0f)
GL11.glVertex3f((x + 1) * TILE_SIZE.toFloat(), y * TILE_SIZE.toFloat(), 0f)
GL11.glColor4f(1f, 1f, 1f, 1f)*/
drawTile(mode, x, y, 0, 0)
}
} // end if (not an air)
} catch (e: NullPointerException) {
// do nothing. WARNING: This exception handling may hide erratic behaviour completely.
}
}
}
// draw - fill up the VBO buffer
worldVBOTexture.rewind()
for (y in 0..VBO_HEIGHT - 1) {
for (x in 0..VBO_WIDTH - 1) {
val vx = x * TILE_SIZEF
val vy = y * TILE_SIZEF
val tileID = regionBuffer[y][x]
val tileX = (tileID % terrainHorizontalTiles) * TILE_SIZEF
val tileY = (tileID / terrainHorizontalTiles) * TILE_SIZEF
worldVBOTexture.put(floatArrayOf( // feed GL_TRIANGLE data (note: bottom-left is zero)
Math.random().toFloat(), Math.random().toFloat(),
Math.random().toFloat(), Math.random().toFloat(),
Math.random().toFloat(), Math.random().toFloat(),
Math.random().toFloat(), Math.random().toFloat()
//Math.random().toFloat() * 4096f, Math.random().toFloat() * 4096f,
//Math.random().toFloat() * 4096f, Math.random().toFloat() * 4096f
)) // FIXME texCoords are wrong?!
}
}
// draw - render the VBO
val texToBind = when (mode) {
TERRAIN, WALL -> tilesTerrain
WIRE -> tilesWire
else -> throw Error("mode not TERRAIN/WALL/WIRE")
}.texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texToBind.textureID)
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT)
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT)
inGLMatrixStack { // disabled for debugging: won't hotswap TEST: what if we inline?
GL11.glTranslatef(WorldCamera.x.clampTileSize().toFloat() - TILE_SIZEF, WorldCamera.y.clampTileSize().toFloat(), 0f)
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY)
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOTextureID)
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0)
// for some reason, using 2 VBOs are faster -- presumably because you must fill EVERY ELEMENT when you're using java.nio.Buffer
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY)
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, worldVBOVertexID)
GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0)
GL11.glDrawArrays(GL11.GL_QUADS, 0, 4 * VBO_WIDTH * VBO_HEIGHT)
}
}
private fun Int.clampTileSize() = this.div(TILE_SIZE).times(TILE_SIZE)
/**
* @param x
* @param y
* @return binary [0-15] 1: up, 2: right, 4: down, 8: left
*/
fun getNearbyTilesInfo(x: Int, y: Int, mode: Int, mark: Int?): Int {
val nearbyTiles = IntArray(4)
nearbyTiles[NEARBY_TILE_KEY_LEFT] = world.getTileFrom(mode, x - 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = world.getTileFrom(mode, x + 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_UP] = world.getTileFrom(mode, x , y - 1) ?: 4906
nearbyTiles[NEARBY_TILE_KEY_DOWN] = world.getTileFrom(mode, x , y + 1) ?: Block.NULL
// try for
var ret = 0
for (i in 0..3) {
if (nearbyTiles[i] == mark) {
ret += 1 shl i // add 1, 2, 4, 8 for i = 0, 1, 2, 3
}
}
return ret
}
fun getNearbyTilesInfoNonSolid(x: Int, y: Int, mode: Int): Int {
val nearbyTiles = IntArray(4)
nearbyTiles[NEARBY_TILE_KEY_LEFT] = world.getTileFrom(mode, x - 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = world.getTileFrom(mode, x + 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_UP] = world.getTileFrom(mode, x , y - 1) ?: 4906
nearbyTiles[NEARBY_TILE_KEY_DOWN] = world.getTileFrom(mode, x , y + 1) ?: Block.NULL
// try for
var ret = 0
for (i in 0..3) {
try {
if (!BlockCodex[nearbyTiles[i]].isSolid &&
!BlockCodex[nearbyTiles[i]].isFluid) {
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
}
} catch (e: ArrayIndexOutOfBoundsException) {
}
}
return ret
}
fun getNearbyTilesInfoWallSticker(x: Int, y: Int): Int {
val nearbyTiles = IntArray(4)
val NEARBY_TILE_KEY_BACK = NEARBY_TILE_KEY_UP
nearbyTiles[NEARBY_TILE_KEY_LEFT] = world.getTileFrom(TERRAIN, x - 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = world.getTileFrom(TERRAIN, x + 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_DOWN] = world.getTileFrom(TERRAIN, x , y + 1) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_BACK] = world.getTileFrom(WALL, x , y) ?: Block.NULL
try {
if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_DOWN]].isSolid)
// has tile on the bottom
return 3
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid
&& BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid)
// has tile on both sides
return 0
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid)
// has tile on the right
return 2
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid)
// has tile on the left
return 1
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_BACK]].isSolid)
// has tile on the back
return 0
else
return 3
} catch (e: ArrayIndexOutOfBoundsException) {
return if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_DOWN]].isSolid)
// has tile on the bottom
3 else 0
}
}
fun getNearbyTilesInfoPlatform(x: Int, y: Int): Int {
val nearbyTiles = IntArray(4)
nearbyTiles[NEARBY_TILE_KEY_LEFT] = world.getTileFrom(TERRAIN, x - 1, y) ?: Block.NULL
nearbyTiles[NEARBY_TILE_KEY_RIGHT] = world.getTileFrom(TERRAIN, x + 1, y) ?: Block.NULL
if ((BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid) ||
isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT]) &&
isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) // LR solid || LR platform
return 0
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT]) &&
!BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) // L solid and not platform && R not solid and not platform
return 4
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT]) &&
!BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT])) // R solid and not platform && L not solid and nto platform
return 6
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT])) // L solid && L not platform
return 3
else if (BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) // R solid && R not platform
return 5
else if ((BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid ||
isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT])) &&
!BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) // L solid or platform && R not solid and not platform
return 1
else if ((BlockCodex[nearbyTiles[NEARBY_TILE_KEY_RIGHT]].isSolid ||
isPlatform(nearbyTiles[NEARBY_TILE_KEY_RIGHT])) &&
!BlockCodex[nearbyTiles[NEARBY_TILE_KEY_LEFT]].isSolid &&
!isPlatform(nearbyTiles[NEARBY_TILE_KEY_LEFT])) // R solid or platform && L not solid and not platform
return 2
else
return 7
}
private fun drawTile(mode: Int, tilewisePosX: Int, tilewisePosY: Int, sheetX: Int, sheetY: Int) {
if (mode == TERRAIN || mode == WALL || mode == WIRE)
writeToRegionBuffer(tilewisePosX, tilewisePosY, sheetX, sheetY)
else
throw IllegalArgumentException()
}
fun clampH(x: Int): Int {
if (x < 0) {
return 0
} else if (x > world.height * TILE_SIZE) {
return world.height * TILE_SIZE
} else {
return x
}
}
fun clampWTile(x: Int): Int {
if (x < 0) {
return 0
} else if (x > world.width) {
return world.width
} else {
return x
}
}
fun clampHTile(x: Int): Int {
if (x < 0) {
return 0
} else if (x > world.height) {
return world.height
} else {
return x
}
}
fun getRenderStartX(): Int = x / TILE_SIZE
fun getRenderStartY(): Int = y / TILE_SIZE
fun getRenderEndX(): Int = clampWTile(getRenderStartX() + (width / TILE_SIZE) + 2)
fun getRenderEndY(): Int = clampHTile(getRenderStartY() + (height / TILE_SIZE) + 2)
fun isConnectSelf(b: Int?): Boolean = TILES_CONNECT_SELF.contains(b)
fun isConnectMutual(b: Int?): Boolean = TILES_CONNECT_MUTUAL.contains(b)
fun isWallSticker(b: Int?): Boolean = TILES_WALL_STICKER.contains(b)
fun isPlatform(b: Int?): Boolean = TILES_WALL_STICKER_CONNECT_SELF.contains(b)
fun isBlendMul(b: Int?): Boolean = TILES_BLEND_MUL.contains(b)
fun tileInCamera(x: Int, y: Int) =
x >= WorldCamera.x.div(TILE_SIZE) && y >= WorldCamera.y.div(TILE_SIZE) &&
x <= WorldCamera.x.plus(width).div(TILE_SIZE) && y <= WorldCamera.y.plus(width).div(TILE_SIZE)
private fun Float.inv() = 1f / this
fun Float.floor() = FastMath.floor(this)
fun Float.ceil() = FastMath.ceil(this)
inline fun inGLMatrixStack(action: () -> Unit) {
GL11.glPushMatrix()
action()
GL11.glPopMatrix()
}
}

View File

@@ -1,10 +1,14 @@
package net.torvald.terrarum.worlddrawer
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.PairedMapLayer
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.blockproperties.BlockCodex
import com.jme3.math.FastMath
import net.torvald.terrarum.*
import net.torvald.terrarum.gameactors.roundInt
import net.torvald.terrarum.itemproperties.ItemCodex.ITEM_TILES
@@ -12,25 +16,31 @@ import net.torvald.terrarum.worlddrawer.WorldCamera.x
import net.torvald.terrarum.worlddrawer.WorldCamera.y
import net.torvald.terrarum.worlddrawer.WorldCamera.height
import net.torvald.terrarum.worlddrawer.WorldCamera.width
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import org.lwjgl.opengl.GL11
import org.newdawn.slick.*
import org.newdawn.slick.imageout.ImageOut
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.util.zip.GZIPInputStream
/**
* Created by minjaesong on 16-01-19.
*/
object BlocksDrawer {
private val world: GameWorld = Terrarum.ingame!!.world
private val world: GameWorld = TerrarumGDX.ingame!!.world
private val TILE_SIZE = FeaturesDrawer.TILE_SIZE
private val TILE_SIZEF = FeaturesDrawer.TILE_SIZE.toFloat()
// TODO modular
val tilesTerrain = SpriteSheet(ModMgr.getPath("basegame", "blocks/terrain.tga.gz"), TILE_SIZE, TILE_SIZE) // 64 MB
val tilesWire = SpriteSheet(ModMgr.getPath("basegame", "blocks/wire.tga.gz"), TILE_SIZE, TILE_SIZE) // 4 MB
//val tilesTerrain = SpriteSheet(ModMgr.getPath("basegame", "blocks/terrain.tga.gz"), TILE_SIZE, TILE_SIZE) // 64 MB
//val tilesWire = SpriteSheet(ModMgr.getPath("basegame", "blocks/wire.tga.gz"), TILE_SIZE, TILE_SIZE) // 4 MB
val tilesTerrain: TextureRegionPack
val tilesWire: TextureRegionPack
val tileItemWall: TextureRegionPack
val tileItemWall = Image(TILE_SIZE * 16, TILE_SIZE * GameWorld.TILES_SUPPORTED / 16) // 4 MB
//val tileItemWall = Image(TILE_SIZE * 16, TILE_SIZE * GameWorld.TILES_SUPPORTED / 16) // 4 MB
val wallOverlayColour = Color(2f/3f, 2f/3f, 2f/3f, 1f)
@@ -52,29 +62,71 @@ object BlocksDrawer {
private val NEARBY_TILE_CODE_LEFT = 8
init {
val tg = tileItemWall.graphics
private val GZIP_READBUF_SIZE = 8192
// initialise item_wall images
(ITEM_TILES).forEach {
tg.drawImage(
tilesTerrain.getSubImage(
(it % 16) * 16,
(it / 16)
),
(it % 16) * TILE_SIZE.toFloat(),
(it / 16) * TILE_SIZE.toFloat(),
wallOverlayColour
)
init {
// hard-coded as tga.gz
val gzFileList = listOf("blocks/terrain.tga.gz", "blocks/wire.tga.gz")
val gzTmpFName = listOf("tmp_terrain.tga", "tmp_wire.tga")
// unzip GZIP temporarily
gzFileList.forEachIndexed { index, filename ->
val terrainTexFile = ModMgr.getGdxFile("basegame", filename)
val gzi = GZIPInputStream(terrainTexFile.read(GZIP_READBUF_SIZE))
val wholeFile = gzi.readBytes()
gzi.close()
val fos = BufferedOutputStream(FileOutputStream(gzTmpFName[index]))
fos.write(wholeFile)
fos.flush()
fos.close()
}
//tg.flush()
//ImageOut.write(tileItemWall, "./tileitemwalltest.png")
val terrainPixMap = Pixmap(Gdx.files.internal(gzTmpFName[0]))
val wirePixMap = Pixmap(Gdx.files.internal(gzTmpFName[1]))
tg.destroy()
// delete temp files
gzTmpFName.forEach { File(it).delete() }
tilesTerrain = TextureRegionPack(Texture(terrainPixMap), TILE_SIZE, TILE_SIZE)
tilesWire = TextureRegionPack(Texture(wirePixMap), TILE_SIZE, TILE_SIZE)
// also dispose unused temp files
//terrainPixMap.dispose() // commented: tileItemWall needs it
wirePixMap.dispose()
// create item_wall images
// --> make pixmap
val tileItemImgPixMap = Pixmap(TILE_SIZE * 16, TILE_SIZE * GameWorld.TILES_SUPPORTED / 16, Pixmap.Format.RGBA8888)
tileItemImgPixMap.pixels.rewind()
(ITEM_TILES).forEach { tileID ->
val tile = tilesTerrain.get((tileID % 16) * 16, (tileID / 16))
// slow memory copy :\ I'm afraid I can't random-access bytebuffer...
for (y in 0..TILE_SIZE - 1) {
for (x in 0..TILE_SIZE - 1) {
tileItemImgPixMap.pixels.putInt(
terrainPixMap.getPixel(
tile.regionX + x,
tile.regionY + y
)
)
}
}
}
tileItemImgPixMap.pixels.rewind()
// turn pixmap into texture
tileItemWall = TextureRegionPack(Texture(tileItemImgPixMap), TILE_SIZE, TILE_SIZE)
tileItemImgPixMap.dispose()
terrainPixMap.dispose() // finally
}
/**
* Connectivity group 01 : artificial tiles
* It holds different shading rule to discriminate with group 02, index 0 is single tile.
@@ -292,51 +344,37 @@ object BlocksDrawer {
fun renderWall(g: Graphics) {
fun renderWall(batch: SpriteBatch) {
/**
* render to camera
*/
blendNormal()
tilesTerrain.startUse()
drawTiles(g, WALL, false)
tilesTerrain.endUse()
blendMul()
g.color = wallOverlayColour
g.fillRect(WorldCamera.x.toFloat(), WorldCamera.y.toFloat(),
WorldCamera.width.toFloat() + 1, WorldCamera.height.toFloat() + 1
)
blendNormal()
batch.color = wallOverlayColour
drawTiles(batch, WALL, false)
}
fun renderTerrain(g: Graphics) {
fun renderTerrain(batch: SpriteBatch) {
/**
* render to camera
*/
blendNormal()
tilesTerrain.startUse()
drawTiles(g, TERRAIN, false) // regular tiles
tilesTerrain.endUse()
batch.color = Color.WHITE
drawTiles(batch, TERRAIN, false) // regular tiles
}
fun renderFront(g: Graphics, drawWires: Boolean) {
fun renderFront(batch: SpriteBatch, drawWires: Boolean) {
/**
* render to camera
*/
blendMul()
tilesTerrain.startUse()
drawTiles(g, TERRAIN, true) // blendmul tiles
tilesTerrain.endUse()
batch.color = Color.WHITE
drawTiles(batch, TERRAIN, true) // blendmul tiles
if (drawWires) {
tilesWire.startUse()
drawTiles(g, WIRE, false)
tilesWire.endUse()
drawTiles(batch, WIRE, false)
}
blendNormal()
@@ -344,7 +382,7 @@ object BlocksDrawer {
private val tileDrawLightThreshold = 2
private fun drawTiles(g: Graphics, mode: Int, drawModeTilesBlendMul: Boolean) {
private fun drawTiles(batch: SpriteBatch, mode: Int, drawModeTilesBlendMul: Boolean) {
val for_y_start = y / TILE_SIZE
val for_y_end = BlocksDrawer.clampHTile(for_y_start + (height / TILE_SIZE) + 2)
@@ -420,13 +458,13 @@ object BlocksDrawer {
// draw a tile
if (drawModeTilesBlendMul) {
if (BlocksDrawer.isBlendMul(thisTile)) {
drawTile(mode, x, y, thisTileX, thisTileY)
drawTile(batch, mode, x, y, thisTileX, thisTileY)
}
}
else {
// do NOT add "if (!isBlendMul(thisTile))"!
// or else they will not look like they should be when backed with wall
drawTile(mode, x, y, thisTileX, thisTileY)
drawTile(batch, mode, x, y, thisTileX, thisTileY)
}
// draw a breakage
@@ -436,8 +474,7 @@ object BlocksDrawer {
val stage = (breakage / maxHealth).times(breakAnimSteps).roundInt()
// actual drawing
if (stage > 0) {
// alpha blending works, but no GL blend func...
drawTile(mode, x, y, 5 + stage, 0)
drawTile(batch, mode, x, y, 5 + stage, 0)
}
}
@@ -592,18 +629,18 @@ object BlocksDrawer {
return 7
}
private fun drawTile(mode: Int, tilewisePosX: Int, tilewisePosY: Int, sheetX: Int, sheetY: Int) {
private fun drawTile(batch: SpriteBatch, mode: Int, tilewisePosX: Int, tilewisePosY: Int, sheetX: Int, sheetY: Int) {
if (mode == TERRAIN || mode == WALL)
tilesTerrain.renderInUse(
FastMath.floor((tilewisePosX * TILE_SIZE).toFloat()),
FastMath.floor((tilewisePosY * TILE_SIZE).toFloat()),
sheetX, sheetY
batch.draw(
tilesTerrain.get(sheetX, sheetY),
(tilewisePosX * TILE_SIZE).toFloat(),
(tilewisePosY * TILE_SIZE).toFloat()
)
else if (mode == WIRE)
tilesWire.renderInUse(
FastMath.floor((tilewisePosX * TILE_SIZE).toFloat()),
FastMath.floor((tilewisePosY * TILE_SIZE).toFloat()),
sheetX, sheetY
batch.draw(
tilesWire.get(sheetX, sheetY),
(tilewisePosX * TILE_SIZE).toFloat(),
(tilewisePosY * TILE_SIZE).toFloat()
)
else
throw IllegalArgumentException()

View File

@@ -1,12 +1,16 @@
package net.torvald.terrarum.worlddrawer
import net.torvald.terrarum.Terrarum
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.blockstats.BlockStats
import com.jme3.math.FastMath
import net.torvald.colourutil.ColourTemp
import net.torvald.terrarum.TerrarumGDX
import net.torvald.terrarum.blendMul
import org.newdawn.slick.*
import net.torvald.terrarum.fillRect
import net.torvald.terrarum.inUse
/**
* Created by minjaesong on 15-12-31.
@@ -32,18 +36,18 @@ object FeaturesDrawer {
Block.SAND_DESERT
, Block.SAND_RED)
fun update(gc: GameContainer, delta_t: Int) {
fun update(delta: Float) {
}
fun render(gc: GameContainer, g: Graphics) {
fun render(batch: SpriteBatch) {
}
/**
* A colour filter used to provide effect that makes whole screen look warmer/cooler,
* usually targeted for the environmental temperature (desert/winterland), hence the name.
*/
fun drawEnvOverlay(g: Graphics) {
val onscreen_tiles_max = FastMath.ceil(Terrarum.HEIGHT * Terrarum.WIDTH / FastMath.sqr(TILE_SIZE.toFloat())) * 2
fun drawEnvOverlay(batch: SpriteBatch) {
val onscreen_tiles_max = FastMath.ceil(Gdx.graphics.height * Gdx.graphics.width / FastMath.sqr (TILE_SIZE.toFloat())) * 2
val onscreen_tiles_cap = onscreen_tiles_max / 4f
val onscreen_cold_tiles = BlockStats.getCount(*TILES_COLD).toFloat()
val onscreen_warm_tiles = BlockStats.getCount(*TILES_WARM).toFloat()
@@ -51,16 +55,15 @@ object FeaturesDrawer {
val colTemp_cold = colTempLinearFunc(onscreen_cold_tiles / onscreen_tiles_cap)
val colTemp_warm = colTempLinearFunc(-(onscreen_warm_tiles / onscreen_tiles_cap))
colTemp = colTemp_warm + colTemp_cold - ENV_COLTEMP_NOON
val zoom = Terrarum.ingame!!.screenZoom
val zoom = TerrarumGDX.ingame!!.screenZoom
blendMul()
g.color = ColourTemp(colTemp)
g.fillRect(
WorldCamera.x * zoom,
batch.color = ColourTemp(colTemp)
batch.fillRect(WorldCamera.x * zoom,
WorldCamera.y * zoom,
Terrarum.WIDTH * if (zoom < 1) 1f / zoom else zoom,
Terrarum.HEIGHT * if (zoom < 1) 1f / zoom else zoom
Gdx.graphics.width * if (zoom < 1) 1f / zoom else zoom,
Gdx.graphics.height * if (zoom < 1) 1f / zoom else zoom
)
}

View File

@@ -1,22 +1,28 @@
package net.torvald.terrarum.worlddrawer
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.glutils.ShapeRenderer
import net.torvald.terrarum.gameactors.Luminous
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blockproperties.BlockCodex
import com.jme3.math.FastMath
import net.torvald.terrarum.TerrarumGDX
import net.torvald.terrarum.gameactors.ActorWithPhysics
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.blockproperties.Block
import org.newdawn.slick.Color
import org.newdawn.slick.Graphics
import net.torvald.terrarum.fillRect
import net.torvald.terrarum.inUse
import java.util.*
/**
* Created by minjaesong on 16-01-25.
*/
typealias RGB10 = Int
object LightmapRenderer {
private val world: GameWorld = Terrarum.ingame!!.world
private val world: GameWorld = TerrarumGDX.ingame!!.world
// TODO if (VBO works on BlocksDrawer) THEN overscan of 256, utilise same technique in here
@@ -24,16 +30,18 @@ object LightmapRenderer {
val overscan_open: Int = Math.min(32, 256f.div(BlockCodex[Block.AIR].opacity and 0xFF).ceil())
val overscan_opaque: Int = Math.min(8, 256f.div(BlockCodex[Block.STONE].opacity and 0xFF).ceil())
val LIGHTMAP_WIDTH = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.WIDTH)
// TODO resize(int, int) -aware
val LIGHTMAP_WIDTH = TerrarumGDX.ingame!!.ZOOM_MIN.inv().times(Gdx.graphics.width)
.div(FeaturesDrawer.TILE_SIZE).ceil() + overscan_open * 2 + 3
val LIGHTMAP_HEIGHT = Terrarum.ingame!!.ZOOM_MIN.inv().times(Terrarum.HEIGHT)
val LIGHTMAP_HEIGHT = TerrarumGDX.ingame!!.ZOOM_MIN.inv().times(Gdx.graphics.height)
.div(FeaturesDrawer.TILE_SIZE).ceil() + overscan_open * 2 + 3
/**
* 8-Bit RGB values
*/
private val lightmap: Array<IntArray> = Array(LIGHTMAP_HEIGHT) { IntArray(LIGHTMAP_WIDTH) }
private val lanternMap = ArrayList<Lantern>(Terrarum.ingame!!.ACTORCONTAINER_INITIAL_SIZE * 4)
private val lightmap: Array<IntArray> = Array(LIGHTMAP_HEIGHT) { IntArray(LIGHTMAP_WIDTH) } // TODO framebuffer?
private val lanternMap = ArrayList<Lantern>(TerrarumGDX.ingame!!.ACTORCONTAINER_INITIAL_SIZE * 4)
private val AIR = Block.AIR
@@ -150,7 +158,7 @@ object LightmapRenderer {
// build noop map
for (i in 0..rect_size) {
val point = edgeToMaskNum(i)
val tile = Terrarum.ingame!!.world.getTileFromTerrain(point.first, point.second) ?: Block.NULL
val tile = TerrarumGDX.ingame!!.world.getTileFromTerrain(point.first, point.second) ?: Block.NULL
val isSolid = BlockCodex[tile].isSolid
noop_mask.set(i, isSolid)
@@ -207,7 +215,7 @@ object LightmapRenderer {
private fun buildLanternmap() {
lanternMap.clear()
Terrarum.ingame!!.actorContainer.forEach { it ->
TerrarumGDX.ingame!!.actorContainer.forEach { it ->
if (it is Luminous && it is ActorWithPhysics) {
// put lanterns to the area the luminantBox is occupying
for (lightBox in it.lightBoxList) {
@@ -237,11 +245,11 @@ object LightmapRenderer {
// TODO devise multithreading on this
var lightLevelThis: Int = 0
val thisTerrain = Terrarum.ingame!!.world.getTileFromTerrain(x, y)
val thisWall = Terrarum.ingame!!.world.getTileFromWall(x, y)
val thisTerrain = TerrarumGDX.ingame!!.world.getTileFromTerrain(x, y)
val thisWall = TerrarumGDX.ingame!!.world.getTileFromWall(x, y)
val thisTileLuminosity = BlockCodex[thisTerrain].luminosity
val thisTileOpacity = BlockCodex[thisTerrain].opacity
val sunLight = Terrarum.ingame!!.world.globalLight
val sunLight = TerrarumGDX.ingame!!.world.globalLight
// MIX TILE
// open air
@@ -274,14 +282,14 @@ object LightmapRenderer {
* maxblend eight values and use it
*/
var ambient = 0
ambient = ambient maxBlend darkenColoured(getLight(x - 1, y - 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
ambient = ambient maxBlend darkenColoured(getLight(x + 1, y - 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
ambient = ambient maxBlend darkenColoured(getLight(x - 1, y + 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
ambient = ambient maxBlend darkenColoured(getLight(x + 1, y + 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
ambient = ambient maxBlend darkenColoured(getLight(x , y - 1) ?: 0, thisTileOpacity)
ambient = ambient maxBlend darkenColoured(getLight(x , y + 1) ?: 0, thisTileOpacity)
ambient = ambient maxBlend darkenColoured(getLight(x - 1, y ) ?: 0, thisTileOpacity)
ambient = ambient maxBlend darkenColoured(getLight(x + 1, y ) ?: 0, thisTileOpacity)
/* + */ambient = ambient maxBlend darkenColoured(getLight(x - 1, y - 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
/* + */ambient = ambient maxBlend darkenColoured(getLight(x + 1, y - 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
/* + */ambient = ambient maxBlend darkenColoured(getLight(x - 1, y + 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
/* + */ambient = ambient maxBlend darkenColoured(getLight(x + 1, y + 1) ?: 0, scaleColour(thisTileOpacity, 1.4142f))
/* * */ambient = ambient maxBlend darkenColoured(getLight(x , y - 1) ?: 0, thisTileOpacity)
/* * */ambient = ambient maxBlend darkenColoured(getLight(x , y + 1) ?: 0, thisTileOpacity)
/* * */ambient = ambient maxBlend darkenColoured(getLight(x - 1, y ) ?: 0, thisTileOpacity)
/* * */ambient = ambient maxBlend darkenColoured(getLight(x + 1, y ) ?: 0, thisTileOpacity)
return lightLevelThis maxBlend ambient
}
else {
@@ -289,7 +297,7 @@ object LightmapRenderer {
}
}
private fun getLightSpecial(x: Int, y: Int): Int? {
private fun getLightForOpaque(x: Int, y: Int): Int? { // ...so that they wouldn't appear too dark
val l = getLight(x, y)
if (l == null) return null
@@ -305,13 +313,14 @@ object LightmapRenderer {
}
}
fun draw(g: Graphics) {
fun draw(batch: SpriteBatch) {
val this_x_start = for_x_start// + overscan_open
val this_x_end = for_x_end// + overscan_open
val this_y_start = for_y_start// + overscan_open
val this_y_end = for_y_end// + overscan_open
// draw
// draw to the
try {
// loop for "scanlines"
for (y in this_y_start..this_y_end) {
@@ -320,24 +329,24 @@ object LightmapRenderer {
while (x < this_x_end) {
// smoothing enabled and zoom is 0.75 or greater
// (zoom of 0.5 should not smoothed, for performance)
if (Terrarum.getConfigBoolean("smoothlighting") ?: false &&
Terrarum.ingame!!.screenZoom >= 0.75) {
if (TerrarumGDX.getConfigBoolean("smoothlighting") ?: false &&
TerrarumGDX.ingame!!.screenZoom >= 0.75) {
val thisLightLevel = getLightSpecial(x, y) ?: 0
val thisLightLevel = getLightForOpaque(x, y) ?: 0
if (x < this_x_end && thisLightLevel == 0
&& getLightSpecial(x, y - 1) == 0) {
&& getLightForOpaque(x, y - 1) == 0) {
try {
// coalesce zero intensity blocks to one
var zeroLevelCounter = 1
while (getLightSpecial(x + zeroLevelCounter, y) == 0) {
while (getLightForOpaque(x + zeroLevelCounter, y) == 0) {
zeroLevelCounter += 1
if (x + zeroLevelCounter >= this_x_end) break
}
g.color = Color(0)
g.fillRect(
batch.color = Color.BLACK
batch.fillRect(
(x.toFloat() * TILE_SIZE).round().toFloat(),
(y.toFloat() * TILE_SIZE).round().toFloat(),
(TILE_SIZE * zeroLevelCounter).toFloat(),
@@ -360,10 +369,10 @@ object LightmapRenderer {
* +-+-+
* d
*/
val a = thisLightLevel maxBlend (getLightSpecial(x, y - 1) ?: thisLightLevel)
val d = thisLightLevel maxBlend (getLightSpecial(x, y + 1) ?: thisLightLevel)
val b = thisLightLevel maxBlend (getLightSpecial(x - 1, y) ?: thisLightLevel)
val c = thisLightLevel maxBlend (getLightSpecial(x + 1, y) ?: thisLightLevel)
val a = thisLightLevel maxBlend (getLightForOpaque(x, y - 1) ?: thisLightLevel)
val d = thisLightLevel maxBlend (getLightForOpaque(x, y + 1) ?: thisLightLevel)
val b = thisLightLevel maxBlend (getLightForOpaque(x - 1, y) ?: thisLightLevel)
val c = thisLightLevel maxBlend (getLightForOpaque(x + 1, y) ?: thisLightLevel)
val colourMapItoL = IntArray(4)
val colMean = (a linMix d) linMix (b linMix c)
@@ -376,10 +385,8 @@ object LightmapRenderer {
for (iy in 0..1) {
for (ix in 0..1) {
g.color = colourMapItoL[iy * 2 + ix].normaliseToColourHDR()
g.fillRect(
batch.color = colourMapItoL[iy * 2 + ix].normaliseToColourHDR()
batch.fillRect(
(x.toFloat() * TILE_SIZE).round()
+ ix * TILE_SIZE / 2f,
(y.toFloat() * TILE_SIZE).round()
@@ -394,23 +401,22 @@ object LightmapRenderer {
// smoothing disabled
else {
try {
val thisLightLevel = getLightSpecial(x, y)
val thisLightLevel = getLightForOpaque(x, y)
// coalesce identical intensity blocks to one
var sameLevelCounter = 1
while (getLightSpecial(x + sameLevelCounter, y) == thisLightLevel) {
while (getLightForOpaque(x + sameLevelCounter, y) == thisLightLevel) {
sameLevelCounter += 1
if (x + sameLevelCounter >= this_x_end) break
}
g.color = (getLightSpecial(x, y) ?: 0).normaliseToColourHDR()
g.fillRect(
batch.color = (getLightForOpaque(x, y) ?: 0).normaliseToColourHDR()
batch.fillRect(
(x.toFloat() * TILE_SIZE).round().toFloat(),
(y.toFloat() * TILE_SIZE).round().toFloat(),
(TILE_SIZE.toFloat().ceil() * sameLevelCounter).toFloat(),
TILE_SIZE.toFloat().ceil().toFloat()
TILE_SIZE.toFloat().ceil().toFloat()
)
x += sameLevelCounter - 1
@@ -428,6 +434,7 @@ object LightmapRenderer {
catch (e: ArrayIndexOutOfBoundsException) {
}
}
val lightScalingMagic = 8f
@@ -439,7 +446,7 @@ object LightmapRenderer {
* @param darken (0-255) per channel
* @return darkened data (0-255) per channel
*/
fun darkenColoured(data: Int, darken: Int): Int {
fun darkenColoured(data: Int, darken: Int): RGB10 {
if (darken < 0 || darken >= COLOUR_RANGE_SIZE)
throw IllegalArgumentException("darken: out of range ($darken)")
@@ -453,7 +460,7 @@ object LightmapRenderer {
return constructRGBFromFloat(r.clampZero(), g.clampZero(), b.clampZero())
}
fun scaleColour(data: Int, scale: Float): Int {
fun scaleColour(data: Int, scale: Float): RGB10 {
val r = data.r() * scale
val g = data.g() * scale
val b = data.b() * scale
@@ -468,7 +475,7 @@ object LightmapRenderer {
* @param brighten (0-255) per channel
* @return brightened data (0-255) per channel
*/
fun brightenColoured(data: Int, brighten: Int): Int {
fun brightenColoured(data: Int, brighten: Int): RGB10 {
if (brighten < 0 || brighten >= COLOUR_RANGE_SIZE)
throw IllegalArgumentException("brighten: out of range ($brighten)")
@@ -486,7 +493,7 @@ object LightmapRenderer {
* @param darken (0-255)
* @return
*/
fun darkenUniformInt(data: Int, darken: Int): Int {
fun darkenUniformInt(data: Int, darken: Int): RGB10 {
if (darken < 0 || darken > CHANNEL_MAX)
throw IllegalArgumentException("darken: out of range ($darken)")
@@ -501,7 +508,7 @@ object LightmapRenderer {
* @param brighten (-1.0 - 1.0) negative means darkening
* @return processed colour
*/
fun alterBrightnessUniform(data: Int, brighten: Float): Int {
fun alterBrightnessUniform(data: Int, brighten: Float): RGB10 {
val modifier = if (brighten < 0)
constructRGBFromFloat(-brighten, -brighten, -brighten)
else
@@ -516,7 +523,7 @@ object LightmapRenderer {
/**
* Deprecated: Fuck it, this vittupää just doesn't want to work
*/
private infix fun Int.screenBlend(other: Int): Int {
private infix fun RGB10.screenBlend(other: Int): RGB10 {
/*val r1 = this.r(); val r2 = other.r(); val newR = 1 - (1 - r1) * (1 - r2)
val g1 = this.g(); val g2 = other.g(); val newG = 1 - (1 - g1) * (1 - g2)
val b1 = this.b(); val b2 = other.b(); val newB = 1 - (1 - b1) * (1 - b2)*/
@@ -546,38 +553,38 @@ object LightmapRenderer {
* @param rgb2
* @return
*/
private inline infix fun Int.maxBlend(other: Int): Int {
private inline infix fun RGB10.maxBlend(other: Int): RGB10 {
return (if (this.rawR() > other.rawR()) this.rawR() else other.rawR()) * MUL_2 +
(if (this.rawG() > other.rawG()) this.rawG() else other.rawG()) * MUL +
(if (this.rawB() > other.rawB()) this.rawB() else other.rawB())
}
private inline infix fun Int.linMix(other: Int): Int {
private inline infix fun RGB10.linMix(other: Int): RGB10 {
return ((this.rawR() + other.rawR()) ushr 1) * MUL_2 +
((this.rawG() + other.rawG()) ushr 1) * MUL +
((this.rawB() + other.rawB()) ushr 1)
}
private inline infix fun Int.colSub(other: Int): Int {
private inline infix fun RGB10.colSub(other: Int): RGB10 {
return ((this.rawR() - other.rawR()).clampChannel()) * MUL_2 +
((this.rawG() - other.rawG()).clampChannel()) * MUL +
((this.rawB() - other.rawB()).clampChannel())
}
private inline infix fun Int.colAdd(other: Int): Int {
private inline infix fun RGB10.colAdd(other: Int): RGB10 {
return ((this.rawR() + other.rawR()).clampChannel()) * MUL_2 +
((this.rawG() + other.rawG()).clampChannel()) * MUL +
((this.rawB() + other.rawB()).clampChannel())
}
inline fun Int.rawR() = this / MUL_2
inline fun Int.rawG() = this % MUL_2 / MUL
inline fun Int.rawB() = this % MUL
inline fun RGB10.rawR() = this / MUL_2
inline fun RGB10.rawG() = this % MUL_2 / MUL
inline fun RGB10.rawB() = this % MUL
/** 0.0 - 1.0 for 0-1023 (0.0 - 0.25 for 0-255) */
inline fun Int.r(): Float = this.rawR() / CHANNEL_MAX_FLOAT
inline fun Int.g(): Float = this.rawG() / CHANNEL_MAX_FLOAT
inline fun Int.b(): Float = this.rawB() / CHANNEL_MAX_FLOAT
inline fun RGB10.r(): Float = this.rawR() / CHANNEL_MAX_FLOAT
inline fun RGB10.g(): Float = this.rawG() / CHANNEL_MAX_FLOAT
inline fun RGB10.b(): Float = this.rawB() / CHANNEL_MAX_FLOAT
/**
@@ -585,14 +592,14 @@ object LightmapRenderer {
* @param offset 2 = R, 1 = G, 0 = B
* @return
*/
fun getRaw(RGB: Int, offset: Int): Int {
fun getRaw(RGB: RGB10, offset: Int): RGB10 {
if (offset == OFFSET_R) return RGB.rawR()
else if (offset == OFFSET_G) return RGB.rawG()
else if (offset == OFFSET_B) return RGB.rawB()
else throw IllegalArgumentException("Channel offset out of range")
}
private fun addRaw(rgb1: Int, rgb2: Int): Int {
private fun addRaw(rgb1: RGB10, rgb2: RGB10): RGB10 {
val newR = (rgb1.rawR() + rgb2.rawR()).clampChannel()
val newG = (rgb1.rawG() + rgb2.rawG()).clampChannel()
val newB = (rgb1.rawB() + rgb2.rawB()).clampChannel()
@@ -600,20 +607,20 @@ object LightmapRenderer {
return constructRGBFromInt(newR, newG, newB)
}
inline fun constructRGBFromInt(r: Int, g: Int, b: Int): Int {
if (r !in 0..CHANNEL_MAX) throw IllegalArgumentException("Red: out of range ($r)")
if (g !in 0..CHANNEL_MAX) throw IllegalArgumentException("Green: out of range ($g)")
if (b !in 0..CHANNEL_MAX) throw IllegalArgumentException("Blue: out of range ($b)")
inline fun constructRGBFromInt(r: Int, g: Int, b: Int): RGB10 {
//if (r !in 0..CHANNEL_MAX) throw IllegalArgumentException("Red: out of range ($r)")
//if (g !in 0..CHANNEL_MAX) throw IllegalArgumentException("Green: out of range ($g)")
//if (b !in 0..CHANNEL_MAX) throw IllegalArgumentException("Blue: out of range ($b)")
return r * MUL_2 +
g * MUL +
b
}
inline fun constructRGBFromFloat(r: Float, g: Float, b: Float): Int {
if (r < 0 || r > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Red: out of range ($r)")
if (g < 0 || g > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Green: out of range ($g)")
if (b < 0 || b > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Blue: out of range ($b)")
inline fun constructRGBFromFloat(r: Float, g: Float, b: Float): RGB10 {
//if (r < 0 || r > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Red: out of range ($r)")
//if (g < 0 || g > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Green: out of range ($g)")
//if (b < 0 || b > CHANNEL_MAX_DECIMAL) throw IllegalArgumentException("Blue: out of range ($b)")
return (r * CHANNEL_MAX).round() * MUL_2 +
(g * CHANNEL_MAX).round() * MUL +
@@ -655,81 +662,83 @@ object LightmapRenderer {
inline fun Int.even(): Boolean = this and 1 == 0
inline fun Int.odd(): Boolean = this and 1 == 1
inline fun Int.normaliseToColour(): Color = Color(
Math.min(this.rawR(), 256),
Math.min(this.rawG(), 256),
Math.min(this.rawB(), 256)
Math.min(this.r(), 1f),
Math.min(this.g(), 1f),
Math.min(this.b(), 1f),
1f
)
val RGB_HDR_LUT = floatArrayOf( // polymonial of 6.0 please refer to work_files/HDRcurveBezierLinIntp.kts
0.0f,0.0f,0.0020097627f,0.0059880256f,0.009966114f,0.013944201f,0.01792211f,0.021899965f,0.025877733f,0.029855346f,0.033832956f,0.037810322f,0.041787688f,0.045764867f,0.04974198f,0.053718954f,
0.05769581f,0.061672557f,0.065649144f,0.06962565f,0.07360197f,0.07757821f,0.08155425f,0.0855302f,0.08950596f,0.0934816f,0.097457066f,0.101432376f,0.10540755f,0.1093825f,0.11335737f,0.11733195f,
0.12130644f,0.12528068f,0.12925476f,0.13322866f,0.1372023f,0.14117579f,0.14514904f,0.14912204f,0.1530949f,0.15706745f,0.16103975f,0.16501188f,0.1689837f,0.17295523f,0.17692655f,0.1808976f,
0.18486828f,0.1888387f,0.19280887f,0.1967787f,0.20074815f,0.20471728f,0.2086861f,0.21265456f,0.21662268f,0.22059034f,0.22455761f,0.22852449f,0.23249097f,0.236457f,0.24042259f,0.24438772f,
0.24835236f,0.2523165f,0.25628012f,0.2602432f,0.26420572f,0.26816767f,0.27212903f,0.27608976f,0.28004986f,0.28400928f,0.28796804f,0.2919261f,0.2958834f,0.2998399f,0.30379558f,0.30775046f,
0.31170452f,0.31565768f,0.31960982f,0.32356104f,0.3275113f,0.33146045f,0.3354085f,0.3393555f,0.34330124f,0.3472458f,0.35118902f,0.355131f,0.3590715f,0.36301064f,0.36694816f,0.3708842f,
0.3748186f,0.37875122f,0.38268217f,0.3866112f,0.3905383f,0.39446342f,0.39838645f,0.40230724f,0.40622574f,0.41014186f,0.4140555f,0.41796657f,0.4218749f,0.42578045f,0.42968303f,0.4335825f,
0.4374788f,0.44137177f,0.44526124f,0.44914708f,0.45302916f,0.45690724f,0.46078113f,0.46465078f,0.468516f,0.47237647f,0.47623205f,0.48008266f,0.4839279f,0.48776764f,0.49160177f,0.49542972f,
0.49925172f,0.503067f,0.5068758f,0.51067746f,0.51447207f,0.51825887f,0.52203804f,0.52580905f,0.5295716f,0.5333255f,0.5370702f,0.5408056f,0.5445313f,0.54824686f,0.55195194f,0.5556463f,
0.5593296f,0.5630012f,0.56666094f,0.57030845f,0.5739433f,0.5775651f,0.58117324f,0.5847676f,0.5883477f,0.59191316f,0.5954636f,0.5989982f,0.60251695f,0.6060194f,0.6095051f,0.61297375f,
0.6164247f,0.6198574f,0.62327176f,0.6266674f,0.63004386f,0.6334008f,0.63673735f,0.6400535f,0.64334905f,0.64662355f,0.6498765f,0.6531072f,0.6563159f,0.65950227f,0.6626658f,0.6658057f,
0.6689224f,0.67201567f,0.6750844f,0.67812896f,0.6811494f,0.6841446f,0.687115f,0.69006073f,0.69298035f,0.69587505f,0.69874376f,0.70158684f,0.7044041f,0.7071951f,0.7099604f,0.7126992f,
0.71541196f,0.7180984f,0.7207585f,0.7233927f,0.7259999f,0.7285815f,0.7311365f,0.7336652f,0.73616827f,0.73864496f,0.74109536f,0.74352026f,0.74591964f,0.7482929f,0.75064045f,0.7529628f,
0.7552601f,0.7575324f,0.7597799f,0.7620023f,0.7641999f,0.7663732f,0.76852244f,0.77064764f,0.77274907f,0.774827f,0.7768816f,0.778913f,0.78092164f,0.7829076f,0.7848708f,0.78681165f,
0.7887305f,0.7906278f,0.7925037f,0.7943586f,0.79619235f,0.7980046f,0.79979676f,0.801569f,0.8033212f,0.80505276f,0.8067654f,0.80845934f,0.81013274f,0.8117882f,0.8134254f,0.8150433f,
0.8166442f,0.8182262f,0.8197912f,0.8213388f,0.8228689f,0.82438266f,0.8258789f,0.82735956f,0.8288232f,0.83027136f,0.8317035f,0.8331199f,0.8345216f,0.83590704f,0.83727884f,0.8386347f,
0.8399765f,0.8413048f,0.84261733f,0.8439169f,0.84520334f,0.84647477f,0.84773356f,0.84897983f,0.85021216f,0.85143167f,0.85263914f,0.8538346f,0.85501665f,0.85618675f,0.85734534f,0.85849243f,
0.8596281f,0.8607512f,0.8618634f,0.86296463f,0.8640551f,0.86513495f,0.8662042f,0.8672625f,0.8683101f,0.86934763f,0.87037516f,0.8713928f,0.8724007f,0.8733989f,0.8743876f,0.8753669f,
0.87633693f,0.87729776f,0.8782496f,0.8791924f,0.8801264f,0.88105166f,0.8819684f,0.8828766f,0.8837764f,0.884668f,0.88555145f,0.88642687f,0.88729435f,0.88815403f,0.8890061f,0.8898505f,
0.8906874f,0.89151704f,0.8923394f,0.8931546f,0.8939628f,0.89476323f,0.8955566f,0.8963433f,0.8971233f,0.8978967f,0.89866376f,0.89942443f,0.90017843f,0.90092534f,0.9016661f,0.9024009f,
0.9031299f,0.90385306f,0.90456975f,0.90527993f,0.9059846f,0.90668386f,0.9073778f,0.9080655f,0.9087471f,0.9094236f,0.91009516f,0.9107616f,0.91142124f,0.9120762f,0.91272646f,0.91337216f,
0.91401106f,0.91464555f,0.91527575f,0.915901f,0.91652024f,0.9171354f,0.9177466f,0.9183519f,0.91895264f,0.9195496f,0.9201418f,0.9207286f,0.92131186f,0.9218912f,0.9224646f,0.9230347f,
0.9236013f,0.9241619f,0.92471933f,0.9252734f,0.92582166f,0.926367f,0.92690873f,0.9274451f,0.9279788f,0.9285084f,0.92903346f,0.929556f,0.9300736f,0.9305878f,0.93109953f,0.9316056f,
0.9321094f,0.9326094f,0.93310535f,0.9335993f,0.93408775f,0.9345741f,0.93505687f,0.9355357f,0.93601286f,0.9364844f,0.93695444f,0.9374203f,0.93788326f,0.9383437f,0.93879974f,0.9392545f,
0.939704f,0.94015217f,0.9405962f,0.9410379f,0.94147664f,0.941912f,0.9423454f,0.9427746f,0.9432027f,0.94362587f,0.9440483f,0.944466f,0.94488263f,0.9452952f,0.94570625f,0.9461137f,
0.9465192f,0.9469216f,0.9473217f,0.9477191f,0.948114f,0.94850636f,0.94889617f,0.9492836f,0.9496684f,0.95005095f,0.950431f,0.95080864f,0.9511839f,0.9515568f,0.95192754f,0.9522956f,
0.9526619f,0.9530252f,0.9533872f,0.95374584f,0.9541036f,0.9544576f,0.9548113f,0.9551606f,0.95550996f,0.95585513f,0.9561999f,0.9565413f,0.95688146f,0.9572192f,0.9575549f,0.9578891f,
0.9582203f,0.95855105f,0.9588778f,0.9592046f,0.9595277f,0.95985f,0.9601699f,0.96048796f,0.96080476f,0.96111846f,0.96143216f,0.9617418f,0.9620512f,0.962358f,0.9626632f,0.96296734f,
0.9632682f,0.96356916f,0.9638666f,0.96416336f,0.9644583f,0.9647509f,0.96504354f,0.96533203f,0.9656206f,0.9659069f,0.96619135f,0.96647555f,0.966756f,0.96703637f,0.9673146f,0.96759105f,
0.96786743f,0.9681399f,0.9684123f,0.968683f,0.9689515f,0.96922004f,0.96948516f,0.9697498f,0.97001344f,0.9702742f,0.970535f,0.9707934f,0.9710503f,0.9713073f,0.9715606f,0.97181374f,
0.9720659f,0.9723153f,0.97256464f,0.97281206f,0.9730577f,0.9733033f,0.9735461f,0.973788f,0.9740299f,0.9742682f,0.9745065f,0.974744f,0.9749787f,0.97521335f,0.97544664f,0.9756777f,
0.97590876f,0.976138f,0.9763655f,0.976593f,0.97681826f,0.97704226f,0.9772662f,0.9774877f,0.97770816f,0.97792864f,0.97814643f,0.97836345f,0.9785805f,0.97879475f,0.9790083f,0.9792219f,
0.9794328f,0.979643f,0.97985315f,0.9800608f,0.9802676f,0.98047435f,0.9806789f,0.9808824f,0.98108584f,0.9812874f,0.9814875f,0.98168766f,0.9818864f,0.98208326f,0.9822801f,0.9824761f,
0.9826697f,0.9828633f,0.9830567f,0.9832471f,0.9834375f,0.98362786f,0.98381555f,0.98400277f,0.9841899f,0.98437536f,0.98455936f,0.9847434f,0.98492664f,0.9851075f,0.9852884f,0.9854693f,
0.9856473f,0.98582506f,0.98600286f,0.986179f,0.9863537f,0.9865284f,0.9867027f,0.98687434f,0.987046f,0.98721766f,0.9873872f,0.98755586f,0.9877245f,0.9878925f,0.98805815f,0.9882238f,
0.98838943f,0.988553f,0.9887157f,0.98887837f,0.9890407f,0.9892004f,0.98936015f,0.9895199f,0.9896781f,0.9898349f,0.9899918f,0.9901486f,0.9903028f,0.99045676f,0.9906107f,0.99076396f,
0.9909151f,0.9910662f,0.9912173f,0.9913669f,0.9915152f,0.9916635f,0.9918118f,0.99195784f,0.99210334f,0.99224883f,0.9923943f,0.992537f,0.9926798f,0.99282247f,0.9929647f,0.9931047f,
0.99324465f,0.99338466f,0.9935238f,0.99366105f,0.9937983f,0.9939356f,0.9940718f,0.9942063f,0.9943409f,0.9944754f,0.9946088f,0.9947407f,0.9948726f,0.99500453f,0.9951353f,0.99526453f,
0.9953938f,0.99552304f,0.99565125f,0.9957779f,0.99590456f,0.99603117f,0.996157f,0.9962811f,0.9964051f,0.99652916f,0.9966528f,0.99677426f,0.99689573f,0.9970172f,0.9971387f,0.99725765f,
0.99737656f,0.99749553f,0.99761444f,0.99773145f,0.99784786f,0.99796426f,0.99808073f,0.9981959f,0.9983098f,0.99842376f,0.99853766f,0.99865115f,0.9987626f,0.99887407f,0.9989855f,0.999097f,
0.9992064f,0.99931544f,0.99942446f,0.99953353f,0.99964154f,0.9997481f,0.99985474f,0.9999613f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f
val RGB_HDR_LUT = floatArrayOf( // polynomial of 6.0 please refer to work_files/HDRcurveBezierLinIntp.kts
0.0000f,0.0000f,0.0020f,0.0060f,0.0100f,0.0139f,0.0179f,0.0219f,0.0259f,0.0299f,0.0338f,0.0378f,0.0418f,0.0458f,0.0497f,0.0537f,
0.0577f,0.0617f,0.0656f,0.0696f,0.0736f,0.0776f,0.0816f,0.0855f,0.0895f,0.0935f,0.0975f,0.1014f,0.1054f,0.1094f,0.1134f,0.1173f,
0.1213f,0.1253f,0.1293f,0.1332f,0.1372f,0.1412f,0.1451f,0.1491f,0.1531f,0.1571f,0.1610f,0.1650f,0.1690f,0.1730f,0.1769f,0.1809f,
0.1849f,0.1888f,0.1928f,0.1968f,0.2007f,0.2047f,0.2087f,0.2127f,0.2166f,0.2206f,0.2246f,0.2285f,0.2325f,0.2365f,0.2404f,0.2444f,
0.2484f,0.2523f,0.2563f,0.2602f,0.2642f,0.2682f,0.2721f,0.2761f,0.2800f,0.2840f,0.2880f,0.2919f,0.2959f,0.2998f,0.3038f,0.3078f,
0.3117f,0.3157f,0.3196f,0.3236f,0.3275f,0.3315f,0.3354f,0.3394f,0.3433f,0.3472f,0.3512f,0.3551f,0.3591f,0.3630f,0.3669f,0.3709f,
0.3748f,0.3788f,0.3827f,0.3866f,0.3905f,0.3945f,0.3984f,0.4023f,0.4062f,0.4101f,0.4141f,0.4180f,0.4219f,0.4258f,0.4297f,0.4336f,
0.4375f,0.4414f,0.4453f,0.4491f,0.4530f,0.4569f,0.4608f,0.4647f,0.4685f,0.4724f,0.4762f,0.4801f,0.4839f,0.4878f,0.4916f,0.4954f,
0.4993f,0.5031f,0.5069f,0.5107f,0.5145f,0.5183f,0.5220f,0.5258f,0.5296f,0.5333f,0.5371f,0.5408f,0.5445f,0.5482f,0.5520f,0.5556f,
0.5593f,0.5630f,0.5667f,0.5703f,0.5739f,0.5776f,0.5812f,0.5848f,0.5883f,0.5919f,0.5955f,0.5990f,0.6025f,0.6060f,0.6095f,0.6130f,
0.6164f,0.6199f,0.6233f,0.6267f,0.6300f,0.6334f,0.6367f,0.6401f,0.6433f,0.6466f,0.6499f,0.6531f,0.6563f,0.6595f,0.6627f,0.6658f,
0.6689f,0.6720f,0.6751f,0.6781f,0.6811f,0.6841f,0.6871f,0.6901f,0.6930f,0.6959f,0.6987f,0.7016f,0.7044f,0.7072f,0.7100f,0.7127f,
0.7154f,0.7181f,0.7208f,0.7234f,0.7260f,0.7286f,0.7311f,0.7337f,0.7362f,0.7386f,0.7411f,0.7435f,0.7459f,0.7483f,0.7506f,0.7530f,
0.7553f,0.7575f,0.7598f,0.7620f,0.7642f,0.7664f,0.7685f,0.7706f,0.7727f,0.7748f,0.7769f,0.7789f,0.7809f,0.7829f,0.7849f,0.7868f,
0.7887f,0.7906f,0.7925f,0.7944f,0.7962f,0.7980f,0.7998f,0.8016f,0.8033f,0.8051f,0.8068f,0.8085f,0.8101f,0.8118f,0.8134f,0.8150f,
0.8166f,0.8182f,0.8198f,0.8213f,0.8229f,0.8244f,0.8259f,0.8274f,0.8288f,0.8303f,0.8317f,0.8331f,0.8345f,0.8359f,0.8373f,0.8386f,
0.8400f,0.8413f,0.8426f,0.8439f,0.8452f,0.8465f,0.8477f,0.8490f,0.8502f,0.8514f,0.8526f,0.8538f,0.8550f,0.8562f,0.8573f,0.8585f,
0.8596f,0.8608f,0.8619f,0.8630f,0.8641f,0.8651f,0.8662f,0.8673f,0.8683f,0.8693f,0.8704f,0.8714f,0.8724f,0.8734f,0.8744f,0.8754f,
0.8763f,0.8773f,0.8782f,0.8792f,0.8801f,0.8811f,0.8820f,0.8829f,0.8838f,0.8847f,0.8856f,0.8864f,0.8873f,0.8882f,0.8890f,0.8899f,
0.8907f,0.8915f,0.8923f,0.8932f,0.8940f,0.8948f,0.8956f,0.8963f,0.8971f,0.8979f,0.8987f,0.8994f,0.9002f,0.9009f,0.9017f,0.9024f,
0.9031f,0.9039f,0.9046f,0.9053f,0.9060f,0.9067f,0.9074f,0.9081f,0.9087f,0.9094f,0.9101f,0.9108f,0.9114f,0.9121f,0.9127f,0.9134f,
0.9140f,0.9146f,0.9153f,0.9159f,0.9165f,0.9171f,0.9177f,0.9184f,0.9190f,0.9195f,0.9201f,0.9207f,0.9213f,0.9219f,0.9225f,0.9230f,
0.9236f,0.9242f,0.9247f,0.9253f,0.9258f,0.9264f,0.9269f,0.9274f,0.9280f,0.9285f,0.9290f,0.9296f,0.9301f,0.9306f,0.9311f,0.9316f,
0.9321f,0.9326f,0.9331f,0.9336f,0.9341f,0.9346f,0.9351f,0.9355f,0.9360f,0.9365f,0.9370f,0.9374f,0.9379f,0.9383f,0.9388f,0.9393f,
0.9397f,0.9402f,0.9406f,0.9410f,0.9415f,0.9419f,0.9423f,0.9428f,0.9432f,0.9436f,0.9440f,0.9445f,0.9449f,0.9453f,0.9457f,0.9461f,
0.9465f,0.9469f,0.9473f,0.9477f,0.9481f,0.9485f,0.9489f,0.9493f,0.9497f,0.9501f,0.9504f,0.9508f,0.9512f,0.9516f,0.9519f,0.9523f,
0.9527f,0.9530f,0.9534f,0.9537f,0.9541f,0.9545f,0.9548f,0.9552f,0.9555f,0.9559f,0.9562f,0.9565f,0.9569f,0.9572f,0.9576f,0.9579f,
0.9582f,0.9586f,0.9589f,0.9592f,0.9595f,0.9599f,0.9602f,0.9605f,0.9608f,0.9611f,0.9614f,0.9617f,0.9621f,0.9624f,0.9627f,0.9630f,
0.9633f,0.9636f,0.9639f,0.9642f,0.9645f,0.9648f,0.9650f,0.9653f,0.9656f,0.9659f,0.9662f,0.9665f,0.9668f,0.9670f,0.9673f,0.9676f,
0.9679f,0.9681f,0.9684f,0.9687f,0.9690f,0.9692f,0.9695f,0.9697f,0.9700f,0.9703f,0.9705f,0.9708f,0.9711f,0.9713f,0.9716f,0.9718f,
0.9721f,0.9723f,0.9726f,0.9728f,0.9731f,0.9733f,0.9735f,0.9738f,0.9740f,0.9743f,0.9745f,0.9747f,0.9750f,0.9752f,0.9754f,0.9757f,
0.9759f,0.9761f,0.9764f,0.9766f,0.9768f,0.9770f,0.9773f,0.9775f,0.9777f,0.9779f,0.9781f,0.9784f,0.9786f,0.9788f,0.9790f,0.9792f,
0.9794f,0.9796f,0.9799f,0.9801f,0.9803f,0.9805f,0.9807f,0.9809f,0.9811f,0.9813f,0.9815f,0.9817f,0.9819f,0.9821f,0.9823f,0.9825f,
0.9827f,0.9829f,0.9831f,0.9832f,0.9834f,0.9836f,0.9838f,0.9840f,0.9842f,0.9844f,0.9846f,0.9847f,0.9849f,0.9851f,0.9853f,0.9855f,
0.9856f,0.9858f,0.9860f,0.9862f,0.9864f,0.9865f,0.9867f,0.9869f,0.9870f,0.9872f,0.9874f,0.9876f,0.9877f,0.9879f,0.9881f,0.9882f,
0.9884f,0.9886f,0.9887f,0.9889f,0.9890f,0.9892f,0.9894f,0.9895f,0.9897f,0.9898f,0.9900f,0.9901f,0.9903f,0.9905f,0.9906f,0.9908f,
0.9909f,0.9911f,0.9912f,0.9914f,0.9915f,0.9917f,0.9918f,0.9920f,0.9921f,0.9922f,0.9924f,0.9925f,0.9927f,0.9928f,0.9930f,0.9931f,
0.9932f,0.9934f,0.9935f,0.9937f,0.9938f,0.9939f,0.9941f,0.9942f,0.9943f,0.9945f,0.9946f,0.9947f,0.9949f,0.9950f,0.9951f,0.9953f,
0.9954f,0.9955f,0.9957f,0.9958f,0.9959f,0.9960f,0.9962f,0.9963f,0.9964f,0.9965f,0.9967f,0.9968f,0.9969f,0.9970f,0.9971f,0.9973f,
0.9974f,0.9975f,0.9976f,0.9977f,0.9978f,0.9980f,0.9981f,0.9982f,0.9983f,0.9984f,0.9985f,0.9987f,0.9988f,0.9989f,0.9990f,0.9991f,
0.9992f,0.9993f,0.9994f,0.9995f,0.9996f,0.9997f,0.9999f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,
1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f,1.0000f // isn't it beautiful?
)
/** To eliminated visible edge on the gradient when 255/1023 is exceeded */
inline fun Int.normaliseToColourHDR() = Color(
RGB_HDR_LUT[this.rawR()],
RGB_HDR_LUT[this.rawG()],
RGB_HDR_LUT[this.rawB()]
RGB_HDR_LUT[this.rawB()],
1f
)
data class Lantern(val posX: Int, val posY: Int, val luminosity: Int)

View File

@@ -1,14 +1,15 @@
package net.torvald.terrarum.worlddrawer
import com.badlogic.gdx.Gdx
import com.jme3.math.FastMath
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.TerrarumGDX
import net.torvald.terrarum.gameworld.GameWorld
/**
* Created by minjaesong on 2016-12-30.
*/
object WorldCamera {
private val world: GameWorld? = Terrarum.ingame?.world
private val world: GameWorld? = TerrarumGDX.ingame?.world
private val TILE_SIZE = FeaturesDrawer.TILE_SIZE
var x: Int = 0
@@ -25,12 +26,12 @@ object WorldCamera {
get() = y + height.ushr(1)
fun update() {
if (Terrarum.ingame != null) {
if (TerrarumGDX.ingame != null) {
val player = Terrarum.ingame!!.player
val player = TerrarumGDX.ingame!!.player
width = FastMath.ceil(Terrarum.WIDTH / Terrarum.ingame!!.screenZoom) // div, not mul
height = FastMath.ceil(Terrarum.HEIGHT / Terrarum.ingame!!.screenZoom)
width = FastMath.ceil(Gdx.graphics.width / TerrarumGDX.ingame!!.screenZoom) // div, not mul
height = FastMath.ceil(Gdx.graphics.height / TerrarumGDX.ingame!!.screenZoom)
// position - (WH / 2)
x = Math.round(// X only: ROUNDWORLD implementation