working UV simulation using alpha channel

This commit is contained in:
minjaesong
2017-07-12 02:35:36 +09:00
parent e01ad32849
commit 7fc2d85c46
30 changed files with 94 additions and 97 deletions

View File

@@ -32,12 +32,12 @@ Creature raw documentation
|name|unit|description|
|----|----|-----------|
|luminosity|30-bit RGB (Int)|Self-glow. Set to 0 for not glowing|
|color|30-bit RGB (Int)|Self-glow. Set to 0 for not glowing|
|name|String|Given (perhaps customised) name|
|racename|STRING_ID|Racename token in language CSV|
|racenameplural|STRING_ID|Racename token in language CSV|
* Note: luminosity uses customised 30-bit RGB. The format specifies ```1.0``` luminosity of white (```#FFFFFF```) be ```0000_0011111111_0011111111_0011111111```, and can hold luminosity range of 0.0-4.0
* Note: color uses customised 30-bit RGB. The format specifies ```1.0``` color of white (```#FFFFFF```) be ```0000_0011111111_0011111111_0011111111```, and can hold color range of 0.0-4.0
## Flags ##

View File

@@ -102,5 +102,5 @@ val kappa = 24389f/27f
* u, v: -100+ - 100+
* (Hundred-based-plus)
*/
data class CIELab(var L: Float = 0f, var a: Float = 0f, var b: Float = 0f, val alpha: Float = 1f)
data class CIELab(var L: Float = 0f, var a: Float = 0f, var b: Float = 0f, var alpha: Float = 1f)

View File

@@ -108,4 +108,4 @@ fun CIELuv.toColor() = this.toXYZ().toColor()
* u, v: -100+ - 100+
* (Hundred-based-plus)
*/
data class CIELuv(var L: Float = 0f, var u: Float = 0f, var v: Float = 0f, val alpha: Float = 1f)
data class CIELuv(var L: Float = 0f, var u: Float = 0f, var v: Float = 0f, var alpha: Float = 1f)

View File

@@ -96,16 +96,16 @@ object CIEXYZUtil {
}
/** Range: X, Y, Z: 0 - 1.0+ (One-based-plus) */
data class CIEXYZ(var X: Float = 0f, var Y: Float = 0f, var Z: Float = 0f, val alpha: Float = 1f) {
data class CIEXYZ(var X: Float = 0f, var Y: Float = 0f, var Z: Float = 0f, var alpha: Float = 1f) {
init {
if (X > 2f || Y > 2f || Z > 2f)
throw IllegalArgumentException("Value range error - CIEXYZ is one-based (0.0 - 1.0+): ($X, $Y, $Z)")
throw IllegalArgumentException("Value range error - this version of CIEXYZ is one-based (0.0 - 1.0+): ($X, $Y, $Z)")
}
}
/** Range: r, g, b: 0 - 1.0 (One-based) */
data class RGB(var r: Float = 0f, var g: Float = 0f, var b: Float = 0f, val alpha: Float = 1f) {
data class RGB(var r: Float = 0f, var g: Float = 0f, var b: Float = 0f, var alpha: Float = 1f) {
constructor(color: Color) : this() {
r = color.r; g = color.g; b = color.b
r = color.r; g = color.g; b = color.b; alpha = color.a
}
}

View File

@@ -9,33 +9,34 @@ import javax.naming.OperationNotSupportedException
* Created by minjaesong on 2017-06-17.
*/
typealias XRGB888 = Int
class GdxColorMap {
constructor(imageFile: FileHandle) {
val pixmap = Pixmap(imageFile)
width = pixmap.width
height = pixmap.height
is2D = pixmap.height == 1
is2D = pixmap.height > 1
data = kotlin.IntArray(pixmap.width * pixmap.height, {
pixmap.getPixel(it % pixmap.width, it / pixmap.width)
})
println("[GdxColorMap] Loading colormap from ${imageFile.name()}; PixmapFormat: ${pixmap.format}; Dimension: $width x $height")
pixmap.dispose()
}
constructor(xrgb888: XRGB888) {
data = intArrayOf(xrgb888.shl(24) + xrgb888.shl(16) + xrgb888.shl(8) + 255)
constructor(color: Color) {
data = intArrayOf(color.toIntBits())
width = 1
height = 1
is2D = false
}
constructor(gradStart: XRGB888, gradEnd: XRGB888) {
data = intArrayOf(gradStart.shl(24) + gradStart.shl(16) + gradStart.shl(8) + 255,
gradEnd.shl(24) + gradEnd.shl(16) + gradEnd.shl(8) + 255)
constructor(gradStart: Color, gradEnd: Color) {
data = intArrayOf(gradStart.toIntBits(), gradEnd.toIntBits())
width = 1
height = 2
is2D = true
@@ -49,9 +50,9 @@ class GdxColorMap {
fun get(x: Int, y: Int): Color = Color(data[y * width + x])
operator fun get(x: Int): Color = if (!is2D) throw OperationNotSupportedException("This is 2D color map") else Color(data[x])
operator fun get(x: Int): Color = if (is2D) throw OperationNotSupportedException("This is 2D color map") else Color(data[x])
fun getRaw(x: Int, y: Int): RGBA8888 = data[y * width + x]
fun getRaw(x: Int): RGBA8888 = if (!is2D) throw OperationNotSupportedException("This is 2D color map") else data[x]
fun getRaw(x: Int): RGBA8888 = if (is2D) throw OperationNotSupportedException("This is 2D color map") else data[x]
}

View File

@@ -152,6 +152,7 @@ class Ingame(val batch: SpriteBatch) : Screen {
var camera = OrthographicCamera(Terrarum.WIDTH.toFloat(), Terrarum.HEIGHT.toFloat())
/** Actually just a mesh of four vertices, two triangles -- not a literal glQuad */
var fullscreenQuad = Mesh(
true, 4, 6,
VertexAttribute.Position(),
@@ -675,12 +676,8 @@ class Ingame(val batch: SpriteBatch) : Screen {
batch.color = Color.WHITE
blendNormal()
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // reset active textureunit to zero (i don't know tbh)
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // reset active textureunit to zero (i don't know tbh, but it won't work without this)
batch.shader = null
batch.color = Color.RED
batch.fillRect(0f, 0f, 16f, 16f)
}
}
@@ -711,9 +708,6 @@ class Ingame(val batch: SpriteBatch) : Screen {
batch.draw(blendedTex, 0f, 0f, blendedTex.width.toFloat(), blendedTex.height.toFloat())
batch.color = Color.GREEN
batch.fillRect(16f, 16f, 16f, 16f)
// an old code.
/*batch.shader = null

View File

@@ -11,7 +11,7 @@ class BlockProp {
var nameKey: String = ""
/** 1.0f for 1023, 0.25f for 255 */
var shadeColR = 0f
var shadeColG = 0f
var shadeColB = 0f
@@ -33,6 +33,7 @@ class BlockProp {
var isVertFriction: Boolean = false
/** 1.0f for 1023, 0.25f for 255 */
var lumColR = 0f
var lumColG = 0f
var lumColB = 0f

View File

@@ -13,12 +13,13 @@ internal object SetGlobalLightOverride : ConsoleCommand {
private set
override fun execute(args: Array<String>) {
if (args.size == 4) {
if (args.size == 5) {
try {
val r = args[1].toFloat()
val g = args[2].toFloat()
val b = args[3].toFloat()
val GL = Color(r, g, b, 1f)
val a = args[4].toFloat()
val GL = Color(r, g, b, a)
lightOverride = true
Terrarum.ingame!!.world.globalLight = GL
@@ -37,6 +38,6 @@ internal object SetGlobalLightOverride : ConsoleCommand {
}
override fun printUsage() {
Echo("Usage: setgl [raw_value|r g b|“none”]")
Echo("Usage: setgl [r g b a|“none”]")
}
}

View File

@@ -49,7 +49,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
if (houseDesignation != null) houseDesignation!!.clear()
}
override var luminosity: Color
override var color: Color
get() = Color(
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f) / LightmapRenderer.MUL_FLOAT,
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f) / LightmapRenderer.MUL_FLOAT,

View File

@@ -12,7 +12,7 @@ import java.util.*
*/
internal class FixtureTikiTorch : FixtureBase(), Luminous {
override var luminosity: Color
override var color: Color
get() = BlockCodex[Block.TORCH].luminosity
set(value) {
throw UnsupportedOperationException()

View File

@@ -8,9 +8,11 @@ import com.badlogic.gdx.graphics.Color
interface Luminous {
/**
* Range of 0.0 - 4.0 for each channel
*
* Recommended implementation:
*
override var luminosity: Color
override var color: Color
get() = Color(
(actorValue.getAsFloat(AVKey.LUMR) ?: 0f) / LightmapRenderer.MUL_FLOAT,
(actorValue.getAsFloat(AVKey.LUMG) ?: 0f) / LightmapRenderer.MUL_FLOAT,
@@ -24,7 +26,7 @@ interface Luminous {
actorValue[AVKey.LUMA] = value.a * LightmapRenderer.MUL_FLOAT
}
*/
var luminosity: Color
var color: Color
/**
* Arguments:

View File

@@ -50,9 +50,9 @@ object PlayerBuilderSigrid {
p.actorValue[AVKey.INTELLIGENT] = true
//p.actorValue[AVKey.LUMR] = 0.84
//p.actorValue[AVKey.LUMR] = 0.93
//p.actorValue[AVKey.LUMR] = 1.37
p.actorValue[AVKey.LUMA] = 0.32
//p.actorValue[AVKey.LUMG] = 0.93
//p.actorValue[AVKey.LUMB] = 1.37
//p.actorValue[AVKey.LUMA] = 1.93
p.actorValue[AVKey.BASEDEFENCE] = 141

View File

@@ -28,7 +28,7 @@ open class ProjectileSimple(
val speed: Int
override var luminosity: Color
override var color: Color
get() = (bulletDatabase[type][OFFSET_LUMINOSITY] as Color).cpy()
set(value) {
}

View File

@@ -11,13 +11,13 @@ class WeaponSwung(val itemID: Int) : ActorWithPhysics(Actor.RenderOrder.MIDTOP),
/**
* Recommended implementation:
*
override var luminosity: Int
override var color: Int
get() = actorValue.getAsInt(AVKey.LUMINOSITY) ?: 0
set(value) {
actorValue[AVKey.LUMINOSITY] = value
}
*/
override var luminosity: Color
override var color: Color
get() = throw UnsupportedOperationException()
set(value) {
}

View File

@@ -33,7 +33,7 @@ class GameWorld(val width: Int, val height: Int) {
/** Meter per second squared. Currently only the downward gravity is supported. No reverse gravity :p */
var gravitation: Vector2 = Vector2(0.0, 9.8)
/** 0.0..1.0+ */
var globalLight = Color(0f,0f,0f,1f)
var globalLight = Color(0f,0f,0f,0f)

View File

@@ -102,7 +102,7 @@ class UIBasicNotifier(private val player: ActorHumanoid?) : UICanvas {
// backplate
batch.color = lightLevel
batch.color = Color(lightLevel.r, lightLevel.g, lightLevel.b, 1f)
batch.draw(atlas.get(0, 0), 0f, 0f)
}

View File

@@ -76,7 +76,7 @@ class UITierOneWatch(private val player: ActorHumanoid?) : UICanvas {
}
// backplate
batch.color = lightLevel
batch.color = Color(lightLevel.r, lightLevel.g, lightLevel.b, 1f)
batch.draw(atlas.get(0, 0), 0f, 0f)
}

View File

@@ -89,14 +89,9 @@ object WeatherMixer {
}
globalLightNow.set(getGlobalLightOfTime(world.time.todaySeconds).mul(0.3f, 0.3f, 0.3f, 0.58f))
}
}
}
private fun Color.set(other: Color) {
this.r = other.r
this.g = other.g
this.b = other.b
this.a = other.a
}
}
/**
@@ -110,9 +105,7 @@ object WeatherMixer {
// calculate global light
val globalLight = getGradientColour(skyboxColourMap, 2, timeNow)
globalLightNow.r = globalLight.r
globalLightNow.g = globalLight.g
globalLightNow.b = globalLight.b
globalLightNow.set(globalLight)
// draw skybox to provided graphics instance
batch.end()
@@ -140,7 +133,6 @@ object WeatherMixer {
fun getGlobalLightOfTime(timeInSec: Int): Color =
getGradientColour(currentWeather.skyboxGradColourMap, 2, timeInSec)
// TODO colour gradient load from image, store to array
fun getGradientColour(colorMap: GdxColorMap, row: Int, timeInSec: Int): Color {
val dataPointDistance = WorldTime.DAY_LENGTH / colorMap.width
@@ -150,7 +142,7 @@ object WeatherMixer {
val colourThis = colorMap.get(phaseThis, row)
val colourNext = colorMap.get(phaseNext, row)
// interpolate R, G and B
// interpolate R, G, B and A
val scale = (timeInSec % dataPointDistance).toFloat() / dataPointDistance // [0.0, 1.0]
val newCol = CIELabUtil.getGradient(scale, colourThis, colourNext)

View File

@@ -80,7 +80,7 @@ object LightmapRenderer {
return null
}
else {
return Color(col.r * MUL_FLOAT, col.g * MUL_FLOAT, col.b * MUL_FLOAT, 1f)
return Color(col.r * MUL_FLOAT, col.g * MUL_FLOAT, col.b * MUL_FLOAT, col.a * MUL_FLOAT)
}
}
@@ -244,10 +244,13 @@ object LightmapRenderer {
..lightBoxY.plus(lightBoxH).div(TILE_SIZE).floorInt()) {
for (x in lightBoxX.div(TILE_SIZE).floorInt()
..lightBoxX.plus(lightBoxW).div(TILE_SIZE).floorInt()) {
lanternMap.add(Lantern(x, y, it.luminosity))
val normalisedColor = it.color.cpy().mul(DIV_FLOAT)
lanternMap.add(Lantern(x, y, normalisedColor))
// Q&D fix for Roundworld anomaly
lanternMap.add(Lantern(x + world.width, y, it.luminosity))
lanternMap.add(Lantern(x - world.width, y, it.luminosity))
lanternMap.add(Lantern(x + world.width, y, normalisedColor))
lanternMap.add(Lantern(x - world.width, y, normalisedColor))
}
}
}
@@ -268,7 +271,7 @@ object LightmapRenderer {
val thisWall = Terrarum.ingame!!.world.getTileFromWall(x, y)
val thisTileLuminosity = BlockCodex[thisTerrain].luminosity // already been div by four
val thisTileOpacity = BlockCodex[thisTerrain].opacity // already been div by four
val sunLight = Terrarum.ingame!!.world.globalLight.cpy().mul(DIV_FLOAT, DIV_FLOAT, DIV_FLOAT, DIV_FLOAT)
val sunLight = Terrarum.ingame!!.world.globalLight.cpy().mul(DIV_FLOAT)
// MIX TILE
// open air
@@ -285,13 +288,12 @@ object LightmapRenderer {
}
// END MIX TILE
for (i in 0..lanternMap.size - 1) {
for (i in 0 until lanternMap.size) {
val lmap = lanternMap[i]
if (lmap.posX == x && lmap.posY == y)
lightLevelThis = lightLevelThis maxBlend lmap.luminosity // maximise to not exceed 1.0 with normal (<= 1.0) light
lightLevelThis = lightLevelThis maxBlend lmap.color // maximise to not exceed 1.0 with normal (<= 1.0) light
}
if (!doNotCalculateAmbient) {
// calculate ambient
/* + * +
@@ -310,11 +312,18 @@ object LightmapRenderer {
/* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x - 1, y ) ?: Color(0f,0f,0f,0f), thisTileOpacity)
/* * */ambientAccumulator = ambientAccumulator maxBlend darkenColoured(getLightInternal(x + 1, y ) ?: Color(0f,0f,0f,0f), thisTileOpacity)
return lightLevelThis maxBlend ambientAccumulator
val ret = lightLevelThis maxBlend ambientAccumulator
return ret
}
else {
return lightLevelThis
val ret = lightLevelThis
return ret
}
}
private fun getLightForOpaque(x: Int, y: Int): Color? { // ...so that they wouldn't appear too dark
@@ -415,7 +424,7 @@ object LightmapRenderer {
data.r * (1f - darken.r * lightScalingMagic),//.clampZero(),
data.g * (1f - darken.g * lightScalingMagic),//.clampZero(),
data.b * (1f - darken.b * lightScalingMagic),//.clampZero(),
data.a * (1f - darken.b * lightScalingMagic))
data.a * (1f - darken.a * lightScalingMagic))
}
private fun scaleSqrt2(data: Color): Color {
@@ -438,7 +447,7 @@ object LightmapRenderer {
data.r * (1f + brighten.r * lightScalingMagic),
data.g * (1f + brighten.g * lightScalingMagic),
data.b * (1f + brighten.b * lightScalingMagic),
data.a * (1f + brighten.b * lightScalingMagic)
data.a * (1f + brighten.a * lightScalingMagic)
)
}
@@ -453,7 +462,7 @@ object LightmapRenderer {
if (darken < 0 || darken > CHANNEL_MAX)
throw IllegalArgumentException("darken: out of range ($darken)")
val darkenColoured = Color(darken, darken, darken, 1f)
val darkenColoured = Color(darken, darken, darken, darken)
return darkenColoured(data, darkenColoured)
}
@@ -543,7 +552,7 @@ object LightmapRenderer {
private fun purgeLightmap() {
for (y in 0..LIGHTMAP_HEIGHT - 1) {
for (x in 0..LIGHTMAP_WIDTH - 1) {
lightmap[y][x] = Color(0f,0f,0f,1f)
lightmap[y][x] = Color(0f,0f,0f,0f)
}
}
}
@@ -559,12 +568,6 @@ object LightmapRenderer {
inline fun Float.ceil() = FastMath.ceil(this)
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.r(), 1f),
Math.min(this.g(), 1f),
Math.min(this.b(), 1f),
1f
)*/
// TODO: float LUT lookup using linear interpolation
@@ -665,7 +668,10 @@ object LightmapRenderer {
1f
)
data class Lantern(val posX: Int, val posY: Int, val luminosity: Color)
/**
* color values are normalised -- 0.0 to 1.0 for 0..1023
*/
data class Lantern(val posX: Int, val posY: Int, val color: Color)
private fun Color.nonZero() = this.r != 0f || this.g != 0f || this.b != 0f || this.a != 0f

View File

@@ -4828,7 +4828,7 @@
"height": 13,
"autoResize": false,
"underline": false,
"text": "+luminosity: Int",
"text": "+color: Int",
"horizontalAlignment": 0,
"verticalAlignment": 5,
"wordWrap": false
@@ -12710,7 +12710,7 @@
"_parent": {
"$ref": "AAAAAAFYpmYlfnwyF/k="
},
"name": "luminosity",
"name": "color",
"visibility": "public",
"isStatic": false,
"isLeaf": false,

Binary file not shown.